fix(deploy): unblock every rebuild on BuildKit's host-network refusal
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 33s
CI / tests-unit (push) Failing after 2m4s
CI / tests-integration (push) Successful in 2m6s
CI / tests-ui (push) Successful in 2m43s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 33s
CI / tests-unit (push) Failing after 2m4s
CI / tests-integration (push) Successful in 2m6s
CI / tests-ui (push) Successful in 2m43s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
Docker 29.1.3 ships BuildKit v0.26, which refuses to grant a build host networking unless each caller passes --allow=network.host. All three rebuild paths asked for it, and `docker compose build` has no flag to grant it, so a rebuild failed immediately with "additional privileges requested". The live container was never replaced, which is exactly the reported symptom: the site kept serving the previous release after a rebuild. Nothing in the build actually needs host networking. It uses the network only for apk, pnpm and next/font/google — all outbound internet, which the default bridge provides. Verified by building both the full runner image and the migrations stage with --no-cache after dropping the flag. Runtime `network_mode: host` stays: blue/green needs per-release host ports (3002/3003) and nginx reaches each slot over 127.0.0.1. The second gap is how a rebuild could still ship the wrong code. ci-deploy.sh stamped every image with HEAD's revision label, and verify-deployed-release.mjs only re-checks that same label, so a dirty working tree produced an image that claimed to be release $sha while containing uncommitted code. docker-update.sh already refused this; ci-deploy.sh now does too, before any build work.
This commit is contained in:
1 parent
48291ab641
commit
fdb7af7ef5
6 files changed
+29
-6
No files matched your search
+8
-1
@@ -3,12 +3,19 @@
|
|||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
x-cms: &cms
|
x-cms: &cms
|
||||||
image: epicnext-cms:${CMS_RELEASE:-local}
|
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:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
NEXT_DEPLOYMENT_ID: ${CMS_RELEASE:-unknown}
|
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
|
network_mode: host
|
||||||
stop_grace_period: 15s
|
stop_grace_period: 15s
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
+17
-1
@@ -395,11 +395,27 @@ if ! grep -qs '^DATABASE_URL=' .env; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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 install --frozen-lockfile
|
||||||
pnpm exec playwright install chromium
|
pnpm exec playwright install chromium
|
||||||
|
|
||||||
echo "Building $image"
|
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" .
|
--build-arg NEXT_DEPLOYMENT_ID="$sha" -t "$image" .
|
||||||
check_current
|
check_current
|
||||||
# Read reports from the already-built image; do not start an extra application.
|
# Read reports from the already-built image; do not start an extra application.
|
||||||
|
|||||||
@@ -39,6 +39,6 @@ pnpm exec playwright install chromium
|
|||||||
export NEWS_E2E_IMAGE="$image"
|
export NEWS_E2E_IMAGE="$image"
|
||||||
export NEWS_E2E_RELEASE="$sha"
|
export NEWS_E2E_RELEASE="$sha"
|
||||||
build_attempted=1
|
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" .
|
--build-arg NEXT_DEPLOYMENT_ID="$sha" -t "$image" .
|
||||||
NEWS_E2E_IMAGE="$image" NEWS_E2E_RELEASE="$sha" node --import tsx e2e/news-real/run.ts
|
NEWS_E2E_IMAGE="$image" NEWS_E2E_RELEASE="$sha" node --import tsx e2e/news-real/run.ts
|
||||||
@@ -123,7 +123,7 @@ if [[ -n "${CMS_IMAGE_REPOSITORY:-}" ]]; then
|
|||||||
docker tag "$app_reference" "epicnext-cms:$CMS_RELEASE"
|
docker tag "$app_reference" "epicnext-cms:$CMS_RELEASE"
|
||||||
docker tag "$remote_migration_image" "$migration_image"
|
docker tag "$remote_migration_image" "$migration_image"
|
||||||
else
|
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
|
docker compose build --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" cms >>"$LOG_FILE" 2>&1
|
||||||
fi
|
fi
|
||||||
expected_image="$(docker image inspect --format '{{.Id}}' "epicnext-cms:$CMS_RELEASE")"
|
expected_image="$(docker image inspect --format '{{.Id}}' "epicnext-cms:$CMS_RELEASE")"
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ describe("isolated branch preflight", () => {
|
|||||||
expect(
|
expect(
|
||||||
result.calls.split("\n").filter((line) => line.startsWith("docker ")),
|
result.calls.split("\n").filter((line) => line.startsWith("docker ")),
|
||||||
).toEqual([
|
).toEqual([
|
||||||
expect.stringContaining("docker build --network=host"),
|
expect.stringContaining("docker build --progress=plain"),
|
||||||
`docker image rm ${image}`,
|
`docker image rm ${image}`,
|
||||||
]);
|
]);
|
||||||
expect(result.calls).not.toMatch(
|
expect(result.calls).not.toMatch(
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pnpm() {
|
|||||||
docker() {
|
docker() {
|
||||||
echo "docker $*" >> "$TEST_DIR/calls"
|
echo "docker $*" >> "$TEST_DIR/calls"
|
||||||
case "$1 $2" in
|
case "$1 $2" in
|
||||||
'build --network=host') [ "$SCENARIO" != build-failure ] ;;
|
'build --progress=plain') [ "$SCENARIO" != build-failure ] ;;
|
||||||
'image rm') [ "$SCENARIO" != cleanup-failure ] ;;
|
'image rm') [ "$SCENARIO" != cleanup-failure ] ;;
|
||||||
*) return 92 ;;
|
*) return 92 ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in new issue
Block a user