Scope note (prior work): The Dockerfile is already a multi-stage build. (see #111).
Do not redo the multi-stage conversion. Scope is: distroless/minimal runtime base, non-root USER (currently absent), read-only-FS compatibility, amd64+arm64 buildx builds with Prisma binaryTargets, Trivy gating, and per-arch container smoke tests.
Description:
Rebuild the container as a multi-stage, distroless (or Chainguard) image running as non-root with read-only filesystem, produce amd64/arm64 builds, and scan with Trivy in CI.
Problem Statement & Context:
A full base image increases attack surface and CVE noise. arm64 support reduces hosting costs and enables Apple Silicon contributors to run identical images.
Scope & Acceptance Criteria:
- Image size reduced ≥ 50% (report before/after); no shell or package manager in final image.
USER non-root, HEALTHCHECK-compatible probes, Prisma engines correctly bundled for both architectures.
- Buildx multi-arch with registry cache; Trivy scan failing on high/critical CVEs with fix available.
- Out of scope: image signing (covered by supply-chain issue).
Implementation Guidelines:
- Key Files/Modules:
Dockerfile, .dockerignore, .github/workflows/cd.yml, prisma/schema.prisma (binaryTargets).
- Design/Architecture: Separate deps, build, and runtime stages;
npm ci --omit=dev in runtime deps stage.
- Edge Cases/Constraints: OpenTelemetry auto-instrumentation must still load; Prisma needs OpenSSL libs.
- Testing: Container smoke test (boot,
/health, one intent flow) for both archs in CI (QEMU for arm64).
Definition of "Done": Common DoD.
Resources:
Common Definition of "Done" (applies in addition to the criteria above):
- Code written, tested, and documented (TSDoc on public APIs, README/runbook/ADR updates where behaviour changes).
- All acceptance criteria met;
npm run lint, npm run typecheck, npm test, npm run test:e2e pass in CI.
- PR follows
.github/PULL_REQUEST_TEMPLATE, uses a Conventional Commit title (enforced by commitlint), includes test output / metrics screenshots, and references the issue.
- New env vars are added to
.env.example variants and src/config/env.validation.ts (the check:env-drift script must pass).
- Reviewed and approved by at least one CODEOWNER.
Description:
Rebuild the container as a multi-stage, distroless (or Chainguard) image running as non-root with read-only filesystem, produce amd64/arm64 builds, and scan with Trivy in CI.
Problem Statement & Context:
A full base image increases attack surface and CVE noise. arm64 support reduces hosting costs and enables Apple Silicon contributors to run identical images.
Scope & Acceptance Criteria:
USERnon-root,HEALTHCHECK-compatible probes, Prisma engines correctly bundled for both architectures.Implementation Guidelines:
Dockerfile,.dockerignore,.github/workflows/cd.yml,prisma/schema.prisma(binaryTargets).npm ci --omit=devin runtime deps stage./health, one intent flow) for both archs in CI (QEMU for arm64).Definition of "Done": Common DoD.
Resources:
Common Definition of "Done" (applies in addition to the criteria above):
npm run lint,npm run typecheck,npm test,npm run test:e2epass in CI..github/PULL_REQUEST_TEMPLATE, uses a Conventional Commit title (enforced by commitlint), includes test output / metrics screenshots, and references the issue..env.examplevariants andsrc/config/env.validation.ts(thecheck:env-driftscript must pass).