Linear: https://linear.app/engineereddev/issue/ENG-267
What's in this PR:
Dockerfile: multi-stage; pnpm 11.28.10 withpnpm fetchlayer caching; builds protocol, crypto, web and server; production deps viapnpm deploy; runtimenode:26-slimas non-rootpneumo(uid 10001),WEB_DIST_DIRset,EXPOSE 8080,CMD ["node","apps/server/dist/index.js"].ARG VERSIONsets the OCI version label and the version/api/healthreports..dockerignorekeeps node_modules, Android, .git, test outputs and.env*(except.env.example) out.docker-compose.yml: theserverprofile builds the image and runs it againstminio/minio-init.mise run e2e:docker(scripts/e2e/docker.ts): builds the image, starts a harness MinIO, runs the container on a private Docker network in direct then proxy mode, runs the dev-client smoke beside it, and asserts health version, web assets, non-root uid, SIGTERM shutdown and image size.check:infraruns hadolint on the Dockerfile (scripts/ci/check.sh, pinned inmise.toml).- ADR 0001 (lead decision): no
railway.json. Railway Config as Code is deprecated: new services can't opt in, and existing files stop being read on 2026-12-01. Deploy settings move to ENG-271 (Railway IaC) and ENG-273 (template). Recommended overlap 0 s, draining 15 s. SPEC §4, §16.3 and §18.2 updated. - ADR 0002 (lead commit): the image cap is raised from 250 MB to 300 MB uncompressed. The spec-mandated
node:26-slimbase alone is 272 MB; Pneumo adds about 19 MB. SPEC §16.1 updated.
Verify (lead, rebased on e5f90f2):
mise run check:infra→ exit 0 (hadolint, shellcheck, biome, workflow validation)mise run e2e:docker→ exit 0. Image 290,785,357 bytes. Direct and proxy: health version, web assets, non-root uid 10001, smoke 7/7 PASS each (authentication, pair+claim, note, link, 2 MB file, push_deleted, revoke 4401), SIGTERM shutdown.docker images:pneumo:eng-267 291MB; no containers left.- Implementer also checked the Compose server profile (MinIO init,
/api/health, web dist).
Deviations:
- No
railway.json(ADR 0001); the image cap is 300 MB (ADR 0002). pnpm deployneeds registry metadata access (offline deploy fails on optionalfseventsmetadata); thepnpm fetchcache and the frozen offline install remain.
🤖 Generated with Claude Code