harden frontend npm ci against proxy drops and verify the toolchain

behind an inspecting proxy npm's parallel fetches intermittently drop and
npm can abort with 'Exit handler never called', leaving an incomplete
node_modules with no vite - which then surfaces as a confusing
'vite: not found' at build time. raise fetch retries/timeouts to ride out
flaky connections and hard-verify node_modules/.bin/vite so a truncated
install fails loudly at the install step.
This commit is contained in:
benjamin.baker
2026-09-02 08:46:54 -04:00
parent aff3bcb8a0
commit 8895997a89

View File

@@ -45,14 +45,28 @@ COPY frontend/package*.json ./frontend/
# guard keeps NODE_EXTRA_CA_CERTS unset on a clean checkout (no cert), so Node
# does not warn about a missing cert path; a proxy-inspected build still gets
# the cert because the file is present.
# Force devDependencies in: vite and the rest of the build toolchain live under
# devDependencies, and some base images / proxied environments default npm to
# omit=dev, which leaves `vite: not found` at build time. A build stage always
# needs them, so include them explicitly regardless of the ambient NODE_ENV.
# Install the frontend dependencies. vite and the rest of the build toolchain
# live under devDependencies, so include them explicitly (--include=dev) in case
# the environment defaults npm to omit=dev. Behind an inspecting proxy (Zscaler)
# npm's many parallel fetches intermittently drop, and npm can even abort with
# "Exit handler never called", leaving an incomplete node_modules with no vite.
# Raise fetch retries/timeouts to ride out flaky connections, then hard-verify
# that the toolchain actually landed so the failure is loud and immediate here
# rather than a confusing "vite: not found" three steps later.
RUN if [ -f /usr/local/share/ca-certificates/corp-root-ca.crt ]; then \
export NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/corp-root-ca.crt; \
fi; \
cd frontend && npm ci --include=dev
cd frontend && \
npm config set fetch-retries 5 && \
npm config set fetch-retry-factor 2 && \
npm config set fetch-retry-mintimeout 20000 && \
npm config set fetch-retry-maxtimeout 120000 && \
npm config set fetch-timeout 600000 && \
npm ci --include=dev --no-audit --no-fund && \
test -x node_modules/.bin/vite || { \
echo "ERROR: node_modules/.bin/vite missing after npm ci (proxy likely truncated the install)."; \
exit 1; \
}
# The frontend keeps its repo-relative layout here, because npm prebuild runs
# `node ../scripts/stage-frontend.mjs`, which stages each plugin's frontend/ into