[E00-S02-T07] amd64 and arm64 are build targets #388

Merged
kpcto merged 2 commits from feature/174 into main 2026-08-29 01:20:03 +00:00
Member

What changed

Implements the [E00-S02-T07] amd64 and arm64 are build targets (#174) on top of the [E00-S02-T01..T06] Compose baseline (#59): the application image now has linux/amd64 and linux/arm64 as build targets, so docker compose build produces a multi-arch image.

  • compose.yaml — the app service's build config now declares build.platforms: [linux/amd64, linux/arm64] (Compose Build spec platforms, supported since Compose v2.10). docker compose build therefore produces a multi-platform image for both architectures. docker compose up still builds and runs the host platform (compose clears the multi-platform list for up/run), so local runs and the T01..T06 real-stack probes are unaffected. Header doc updated: T07 is in scope; T08 (secrets) remains a later task. Rollback note: drop the platforms list from the app build config.
  • apps/server/Dockerfile — header doc-accuracy only: T07 is a Compose-level concern (build.platforms). The image needs no change — both stages already build on the official multi-arch node:24.19.0-bookworm-slim base (which publishes linux/amd64 and linux/arm64 manifests) and the build has no native dependencies (pnpm install + tsc are architecture-independent), so the declared targets are actually buildable.
  • tests/build-targets.test.mjs (new) — locks in both acceptance criteria: static assertions that the app service's build.platforms lists both linux/amd64 and linux/arm64 and that every Dockerfile stage uses the multi-arch base image; non-vacuous mutation probes (removing either target, replacing arm64 with a non-arm64 platform, dropping or emptying the whole list, or moving platforms onto the image-only db service — all fail); and two Docker-gated probes for machines with Docker: docker compose build --print emits a bake config whose app target lists both platforms (a real docker compose build is multi-arch), and docker buildx imagetools inspect on the base image reports both linux/amd64 and linux/arm64 manifests (the targets are realizable).

Explicitly out of scope per the brief, not touched: read-only root filesystem (E00-S02-T06 — unchanged behavior), secrets not embedded (E00-S02-T08).

Criterion → test table

Acceptance criterion Test (fails without the committed state)
amd64 is a build target tests/build-targets.test.mjs — "compose.yaml declares amd64 and arm64 as build targets (app service build.platforms)" (static: the app service's build.platforms must include linux/amd64). Mutation probes removing the amd64 entry, dropping/emptying the whole platforms list, or moving platforms onto db all fail. Docker-gated bake-config probe: docker compose build --print must list linux/amd64 in the app target's platforms; imagetools probe: docker buildx imagetools inspect node:24.19.0-bookworm-slim must report a linux/amd64 manifest
arm64 is a build target tests/build-targets.test.mjs — same static test: build.platforms must include linux/arm64. Mutation probes removing the arm64 entry or replacing it with a non-arm64 platform (linux/386) both fail. Docker-gated bake-config probe: the app target must list linux/arm64; imagetools probe: the base image must report a linux/arm64 manifest

Test plan executed

  • node --test tests/build-targets.test.mjs → 9/9 pass, 2 skipped (the Docker-gated probes skip cleanly where no Docker daemon exists; this sandbox has no Docker). Against a clean main worktree the same file gives 7 fail / 2 pass / 2 skip — the criteria genuinely fail without the committed state ✓
  • node --test tests/compose-config.test.mjs tests/build-targets.test.mjs tests/readonly-rootfs.test.mjs tests/non-root-user.test.mjs → 40/40 pass, 7 skipped — the existing T01..T06 suites still pass with the new build.platforms key (the repo's block-YAML parser reads it correctly) ✓
  • node --test tests/*.test.mjs (full suite) → 86 pass / 12 fail / 7 skip, and the identical 12 failures exist on clean main (77 pass / 12 fail / 5 skip in a fresh worktree) — frozen-install / root-commands / strict-tsconfig / node-engine / typescript-pin suites need pnpm install + Node 24, which this environment lacks (no node_modules, Node 22.23.2 here). My branch adds +9 passing tests and +2 Docker-gated skips, zero new failures ✓
  • The Docker-gated probes are exactly the acceptance sequence (docker compose build → bake config lists both platforms; base image manifest list contains both architectures) and are designed to run on CI/dev machines with Docker + buildx.

Risks / notes

  • build.platforms is the Compose Build spec's declaration of image build targets (docker compose build → multi-arch image). docker compose up deliberately builds/runs only the host platform (compose clears the multi-platform list for up/run), so the T01..T06 real-stack probes (docker compose up -d) and local dev flows are unaffected — verified against the docker/compose applyPlatforms logic.
  • The image itself is unchanged: both stages use the official multi-arch node:24.19.0-bookworm-slim base and the build has no native dependencies, so amd64/arm64 targets need no Dockerfile changes. If a later story adds native modules (e.g. argon2), the multi-stage build may need cross-compile/emulation handling — out of scope here.
  • Docker-gated tests skip without a daemon, so the suite stays green everywhere while giving real build-target validation where Docker exists (same pattern as T01..T06).

Refs #174

## What changed Implements the [E00-S02-T07] amd64 and arm64 are build targets (#174) on top of the [E00-S02-T01..T06] Compose baseline (#59): the application image now has **`linux/amd64` and `linux/arm64` as build targets**, so `docker compose build` produces a multi-arch image. - **`compose.yaml`** — the `app` service's build config now declares **`build.platforms: [linux/amd64, linux/arm64]`** (Compose Build spec `platforms`, supported since Compose v2.10). `docker compose build` therefore produces a multi-platform image for both architectures. `docker compose up` still builds and runs the host platform (compose clears the multi-platform list for `up`/`run`), so local runs and the T01..T06 real-stack probes are unaffected. Header doc updated: T07 is in scope; T08 (secrets) remains a later task. Rollback note: drop the `platforms` list from the `app` build config. - **`apps/server/Dockerfile`** — header doc-accuracy only: T07 is a Compose-level concern (`build.platforms`). The image needs no change — both stages already build on the official **multi-arch `node:24.19.0-bookworm-slim`** base (which publishes linux/amd64 and linux/arm64 manifests) and the build has no native dependencies (pnpm install + tsc are architecture-independent), so the declared targets are actually buildable. - **`tests/build-targets.test.mjs`** (new) — locks in both acceptance criteria: static assertions that the `app` service's `build.platforms` lists both `linux/amd64` and `linux/arm64` and that every Dockerfile stage uses the multi-arch base image; non-vacuous mutation probes (removing either target, replacing arm64 with a non-arm64 platform, dropping or emptying the whole list, or moving platforms onto the image-only `db` service — all fail); and two Docker-gated probes for machines with Docker: `docker compose build --print` emits a bake config whose app target lists both platforms (a real `docker compose build` is multi-arch), and `docker buildx imagetools inspect` on the base image reports both `linux/amd64` and `linux/arm64` manifests (the targets are realizable). Explicitly out of scope per the brief, **not touched**: read-only root filesystem (E00-S02-T06 — unchanged behavior), secrets not embedded (E00-S02-T08). ## Criterion → test table | Acceptance criterion | Test (fails without the committed state) | | --- | --- | | `amd64` is a build target | `tests/build-targets.test.mjs` — **"compose.yaml declares amd64 and arm64 as build targets (app service build.platforms)"** (static: the `app` service's `build.platforms` must include `linux/amd64`). Mutation probes removing the amd64 entry, dropping/emptying the whole platforms list, or moving platforms onto `db` all fail. Docker-gated **bake-config probe**: `docker compose build --print` must list `linux/amd64` in the app target's platforms; **imagetools probe**: `docker buildx imagetools inspect node:24.19.0-bookworm-slim` must report a `linux/amd64` manifest | | `arm64` is a build target | `tests/build-targets.test.mjs` — same static test: `build.platforms` must include `linux/arm64`. Mutation probes removing the arm64 entry or replacing it with a non-arm64 platform (`linux/386`) both fail. Docker-gated **bake-config probe**: the app target must list `linux/arm64`; **imagetools probe**: the base image must report a `linux/arm64` manifest | ## Test plan executed - `node --test tests/build-targets.test.mjs` → **9/9 pass, 2 skipped** (the Docker-gated probes skip cleanly where no Docker daemon exists; this sandbox has no Docker). Against a clean `main` worktree the same file gives **7 fail / 2 pass / 2 skip** — the criteria genuinely fail without the committed state ✓ - `node --test tests/compose-config.test.mjs tests/build-targets.test.mjs tests/readonly-rootfs.test.mjs tests/non-root-user.test.mjs` → **40/40 pass, 7 skipped** — the existing T01..T06 suites still pass with the new `build.platforms` key (the repo's block-YAML parser reads it correctly) ✓ - `node --test tests/*.test.mjs` (full suite) → **86 pass / 12 fail / 7 skip**, and the **identical 12 failures exist on clean `main`** (77 pass / 12 fail / 5 skip in a fresh worktree) — frozen-install / root-commands / strict-tsconfig / node-engine / typescript-pin suites need `pnpm install` + Node 24, which this environment lacks (no `node_modules`, Node 22.23.2 here). My branch adds **+9 passing tests and +2 Docker-gated skips, zero new failures** ✓ - The Docker-gated probes are exactly the acceptance sequence (`docker compose build` → bake config lists both platforms; base image manifest list contains both architectures) and are designed to run on CI/dev machines with Docker + buildx. ## Risks / notes - `build.platforms` is the Compose Build spec's declaration of image build targets (`docker compose build` → multi-arch image). `docker compose up` deliberately builds/runs only the host platform (compose clears the multi-platform list for `up`/`run`), so the T01..T06 real-stack probes (`docker compose up -d`) and local dev flows are unaffected — verified against the docker/compose `applyPlatforms` logic. - The image itself is unchanged: both stages use the official multi-arch `node:24.19.0-bookworm-slim` base and the build has no native dependencies, so amd64/arm64 targets need no Dockerfile changes. If a later story adds native modules (e.g. argon2), the multi-stage build may need cross-compile/emulation handling — out of scope here. - Docker-gated tests `skip` without a daemon, so the suite stays green everywhere while giving real build-target validation where Docker exists (same pattern as T01..T06). Refs #174
bot-implementer added 2 commits 2026-08-29 01:13:55 +00:00
kpcto merged commit 25d7dc836b into main 2026-08-29 01:20:03 +00:00
kpcto deleted branch feature/174 2026-08-29 01:20:03 +00:00
Sign in to join this conversation.