diff --git a/docker-compose.yml b/docker-compose.yml index 76b19982..14cca26e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,12 +3,19 @@ # ───────────────────────────────────────────────────────────────────────────── x-cms: &cms image: epicnext-cms:${CMS_RELEASE:-local} + # No `network: host` on the build. BuildKit (v0.26, Docker 29) refuses to grant + # host networking unless every caller passes --allow=network.host, and + # `docker compose build` has no such flag — so asking for it here turned every + # rebuild into an immediate "additional privileges requested" failure, which + # left the previous release serving traffic. The build only needs outbound + # internet (apk, pnpm, next/font/google), which the default bridge provides. build: context: . dockerfile: Dockerfile args: NEXT_DEPLOYMENT_ID: ${CMS_RELEASE:-unknown} - network: host + # Runtime host networking IS required: blue/green needs per-release host ports + # (3002/3003) and nginx reaches the slot over 127.0.0.1. network_mode: host stop_grace_period: 15s restart: unless-stopped diff --git a/scripts/ci-deploy.sh b/scripts/ci-deploy.sh index f4111c47..091d36a5 100644 --- a/scripts/ci-deploy.sh +++ b/scripts/ci-deploy.sh @@ -395,11 +395,27 @@ if ! grep -qs '^DATABASE_URL=' .env; then exit 1 fi +# De image krijgt het label van $sha, en `verify-deployed-release.mjs` controleert +# later alleen díe label. Zonder deze check bouwt een vuile werkboom dus een image +# die zegt release $sha te zijn terwijl er ongecommitte code in zit — precies het +# scenario "rebuilden levert geen nieuwe code". `docker-update.sh` deed dit al. +# `--untracked-files=normal` laat gitignored artefacten (.next, coverage, +# build-reports) buiten beschouwing; die worden toch niet meegebouwd. +if [ -n "$(git status --porcelain --untracked-files=normal)" ]; then + echo "Error: de werkboom is niet schoon, dus de image zou een verkeerd release-label krijgen." >&2 + echo " Commit of stash de wijzigingen en draai opnieuw." >&2 + echo " De live release is niet aangeraakt." >&2 + git status --short >&2 + exit 1 +fi + pnpm install --frozen-lockfile pnpm exec playwright install chromium echo "Building $image" -DOCKER_BUILDKIT=1 docker build --network=host --progress=plain --cache-from epicnext-cms:latest \ +# No --network=host: BuildKit only grants it via --allow=network.host, and the +# build needs nothing but outbound internet (apk, pnpm, next/font/google). +DOCKER_BUILDKIT=1 docker build --progress=plain --cache-from epicnext-cms:latest \ --build-arg NEXT_DEPLOYMENT_ID="$sha" -t "$image" . check_current # Read reports from the already-built image; do not start an extra application. diff --git a/scripts/ci-preflight.sh b/scripts/ci-preflight.sh index 348460ab..5dc86682 100644 --- a/scripts/ci-preflight.sh +++ b/scripts/ci-preflight.sh @@ -39,6 +39,6 @@ pnpm exec playwright install chromium export NEWS_E2E_IMAGE="$image" export NEWS_E2E_RELEASE="$sha" build_attempted=1 -DOCKER_BUILDKIT=1 docker build --network=host --progress=plain \ +DOCKER_BUILDKIT=1 docker build --progress=plain \ --build-arg NEXT_DEPLOYMENT_ID="$sha" -t "$image" . NEWS_E2E_IMAGE="$image" NEWS_E2E_RELEASE="$sha" node --import tsx e2e/news-real/run.ts \ No newline at end of file diff --git a/scripts/docker-update.sh b/scripts/docker-update.sh index e7935aa4..4bf9d545 100755 --- a/scripts/docker-update.sh +++ b/scripts/docker-update.sh @@ -123,7 +123,7 @@ if [[ -n "${CMS_IMAGE_REPOSITORY:-}" ]]; then docker tag "$app_reference" "epicnext-cms:$CMS_RELEASE" docker tag "$remote_migration_image" "$migration_image" else - docker build --network=host --target migrations --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" -t "$migration_image" . >>"$LOG_FILE" 2>&1 + docker build --target migrations --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" -t "$migration_image" . >>"$LOG_FILE" 2>&1 docker compose build --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" cms >>"$LOG_FILE" 2>&1 fi expected_image="$(docker image inspect --format '{{.Id}}' "epicnext-cms:$CMS_RELEASE")" diff --git a/src/lib/ci-preflight.test.ts b/src/lib/ci-preflight.test.ts index 185aa84f..c35fb79a 100644 --- a/src/lib/ci-preflight.test.ts +++ b/src/lib/ci-preflight.test.ts @@ -94,7 +94,7 @@ describe("isolated branch preflight", () => { expect( result.calls.split("\n").filter((line) => line.startsWith("docker ")), ).toEqual([ - expect.stringContaining("docker build --network=host"), + expect.stringContaining("docker build --progress=plain"), `docker image rm ${image}`, ]); expect(result.calls).not.toMatch( diff --git a/src/test/ci-preflight-harness.sh b/src/test/ci-preflight-harness.sh index e317e860..d20405b2 100644 --- a/src/test/ci-preflight-harness.sh +++ b/src/test/ci-preflight-harness.sh @@ -11,7 +11,7 @@ pnpm() { docker() { echo "docker $*" >> "$TEST_DIR/calls" case "$1 $2" in - 'build --network=host') [ "$SCENARIO" != build-failure ] ;; + 'build --progress=plain') [ "$SCENARIO" != build-failure ] ;; 'image rm') [ "$SCENARIO" != cleanup-failure ] ;; *) return 92 ;; esac