Files
landing-app/tools/docker-install-deps.sh
pigui a226cbddbd Fail the image build when the Nexus token is missing
`docker compose build` without NEXUS_TOKEN produced a Nexus 401 forty
seconds in, worded as a credentials problem when it was really an unset
variable. The mount's `required=true` asserts the secret was *declared*,
not that it holds anything, so an empty one sailed past it and npm sent
an empty `_authToken`.

The install moves to tools/docker-install-deps.sh, which checks the
secret before touching the network and fails in under a second with the
three ways to supply it. It is a file rather than inline shell because
BuildKit echoes an inline command twice on failure and buries the
message.

Also ignore .env. It carries NEXUS_TOKEN, compose reads it at build
time, and it was not gitignored — .env.example stays tracked. Nothing
had been committed: the only prior commit predates all of this.

Verified: empty token fails in 0.2s with the message; .env and the
environment variable both build; the image carries no trace of the
token and serves the full page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 21:56:11 +02:00

53 lines
1.5 KiB
Bash
Executable File

#!/bin/sh
# Installs the workspace's dependencies inside the image.
#
# Split out of the Dockerfile so a failure prints this file's own message
# instead of BuildKit echoing a twenty-line inline shell twice.
set -eu
TOKEN_FILE=/run/secrets/nexus_token
NEXUS_PATH=//nexus.pireon.dev/repository/npm-releases/
# `required=true` on the mount only asserts the secret was declared, not that it
# holds anything. An empty one sails past it and surfaces four hundred packages
# later as a Nexus 401 that reads like a credentials problem.
if [ ! -s "$TOKEN_FILE" ]; then
cat >&2 <<'MSG'
ERROR: the nexus_token build secret is empty.
@pi/ui is published to the private Nexus, so the install needs a token.
compose: NEXUS_TOKEN=... docker compose build
or put NEXUS_TOKEN in .env, which compose reads on its own
docker: docker build --secret id=nexus_token,env=NEXUS_TOKEN .
Locally the value is the one already in ~/.npmrc:
grep nexus.pireon.dev ~/.npmrc
MSG
exit 1
fi
# Written and removed inside a single layer, so it leaves no trace even in this
# stage — which is discarded anyway.
NPMRC=/tmp/npmrc
printf '%s:_authToken=%s\n' "$NEXUS_PATH" "$(cat "$TOKEN_FILE")" > "$NPMRC"
if NPM_CONFIG_USERCONFIG="$NPMRC" npm ci --no-audit --no-fund; then
rm -f "$NPMRC"
else
status=$?
rm -f "$NPMRC"
if [ "$status" -ne 0 ]; then
echo "" >&2
echo "npm ci failed. If the error above is a 401 from nexus.pireon.dev," >&2
echo "the token was present but is not valid for npm-releases." >&2
echo "" >&2
fi
exit "$status"
fi