diff --git a/Dockerfile b/Dockerfile index 5ed4a30..89de383 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,18 @@ # syntax=docker/dockerfile:1 # -# Build args let CI inject mirrors for faster builds in CN networks; the -# defaults keep the Dockerfile portable so anyone can `docker build .` -# without extra configuration. +# Base images are pinned to the project's registry mirrors so the build is +# deterministic and avoids Docker Hub / ghcr.io pull failures in CN networks. +# Trade-off: `docker build .` requires reachability of these registries. # -# NODE_IMAGE – stage 1 base (Docker Hub library/node) -# NPM_REGISTRY – npm registry for `npm ci` -# UV_IMAGE – stage 2 base (ghcr.io/astral-sh/uv) -# APT_MIRROR – Debian apt mirror host (e.g. mirrors.aliyun.com); empty = official -# UV_INDEX_URL – PyPI index URL passed through to `uv sync`; empty = official +# NPM_REGISTRY – npm registry for `npm ci` (build-arg) +# APT_MIRROR – Debian apt mirror host (build-arg, empty = official) +# UV_INDEX_URL – PyPI index URL passed through to `uv sync` (build-arg, empty = official) # Stage 1: build the cloud-console Vue 3 SPA. # NOTE: do not set NODE_ENV=production here — vue-tsc and typescript are # devDependencies required by `npm run build`. -ARG NODE_IMAGE=node:20-bookworm-slim ARG NPM_REGISTRY=https://registry.npmjs.org -FROM ${NODE_IMAGE} AS frontend +FROM registry.jerryyan.net/library/node:20-bookworm-slim AS frontend # Re-declare inside the stage so --build-arg values (or the global default) # are visible to RUN. Without this, ARGs declared before FROM are inaccessible. ARG NPM_REGISTRY @@ -26,8 +23,7 @@ COPY cloud-console/ ./ RUN npm run build # Stage 2: the existing Python image, now carrying the SPA build output. -ARG UV_IMAGE=ghcr.io/astral-sh/uv:python3.14-bookworm-slim -FROM ${UV_IMAGE} +FROM registry-ghcr.jerryyan.top/astral-sh/uv:python3.14-bookworm-slim ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ diff --git a/Jenkinsfile b/Jenkinsfile index c9ef232..c3ce7eb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -22,13 +22,12 @@ pipeline { booleanParam(name: 'PUSH', defaultValue: true, description: 'Push the image to REGISTRY after a successful build') // Mirror overrides passed to `docker build` as --build-arg. Defaults target - // CN networks so Jenkins builds don't time out pulling from Docker Hub / - // ghcr.io / npmjs.org / deb.debian.org. Override or blank any of these to - // build against the official upstreams. - string(name: 'NODE_IMAGE', defaultValue: 'registry.jerryyan.net/library/node:20-bookworm-slim', description: 'Stage 1 base image (Docker Hub library/node proxy)') - string(name: 'NPM_REGISTRY', defaultValue: 'https://registry.npmmirror.com', description: 'npm registry URL used by `npm ci`') - string(name: 'UV_IMAGE', defaultValue: 'registry-ghcr.jerryyan.top/astral-sh/uv:python3.14-bookworm-slim', description: 'Stage 2 base image (ghcr.io/astral-sh/uv proxy)') - string(name: 'APT_MIRROR', defaultValue: 'mirrors.aliyun.com', description: 'Debian apt mirror host (e.g. mirrors.aliyun.com). Empty = deb.debian.org') + // CN networks so Jenkins builds don't time out pulling from npmjs.org / + // deb.debian.org / PyPI. Override or blank any of these to build against + // the official upstreams. Base images (node, uv) are pinned in the + // Dockerfile FROM lines and no longer overridable here. + string(name: 'NPM_REGISTRY', defaultValue: 'https://registry.npmmirror.com', description: 'npm registry URL used by `npm ci`') + string(name: 'APT_MIRROR', defaultValue: 'mirrors.aliyun.com', description: 'Debian apt mirror host (e.g. mirrors.aliyun.com). Empty = deb.debian.org') } environment { @@ -91,7 +90,7 @@ pipeline { // Pass every mirror override through as --build-arg. Empty values // are skipped so the Dockerfile ARG default applies. def buildArgs = [] - ["NODE_IMAGE", "NPM_REGISTRY", "UV_IMAGE", "APT_MIRROR", "UV_INDEX_URL"].each { name -> + ["NPM_REGISTRY", "APT_MIRROR", "UV_INDEX_URL"].each { name -> def v = params[name]?.toString()?.trim() if (v) { buildArgs << "--build-arg ${name}=${v}"