feat(build): harden and shrink dockerfile#644
Conversation
|
Changeset detected — the following file(s) will be released with this PR: |
📝 WalkthroughWalkthroughThe ChangesDistroless Backend Container Build
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
swap to distroless runtime image fix yarn berry cache path tree-shake production node_modules Signed-off-by: Pinguladora <50406923+Pinguladora@users.noreply.github.com>
pruning was too agressive breaking image upon booting explicit Docker Hub path so it cannot be confused or typosquatted in any way Signed-off-by: Pinguladora <50406923+Pinguladora@users.noreply.github.com>
Helm chart already pass node as the first argument so adjust to it, at least temporary Signed-off-by: Pinguladora <50406923+Pinguladora@users.noreply.github.com>
Signed-off-by: Alvaro <212876443+aechegoyan@users.noreply.github.com>
2dc1070 to
8e03d00
Compare
|
Forgot to add, it would be interesting to consider having a dev / quick-start variant image through a Dockerfile.dev or similar so sqlite3 stuff can be pruned too, which should remove another ~30MB. |
LakshanSS
left a comment
There was a problem hiding this comment.
Thank you for your contribution @Pinguladora!
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Purpose
The current container image (at packages/backend/Dockerfile) produces a ~1.6 GB runtime image that ships the full node:22-bookworm-slim userland (apt, dpkg, g++, libsqlite3-dev, etc.) into the final image even if they aren't necessary. This come with quite a few downsides:
No tracked issue, opened directly from a downstream POC where this surfaced via Trivy reporting ~200 HIGH+CRITICAL findings per Backstage pod, the majority of them in the runtime stage's build toolchain rather than in node_modules.
Goals
Approach
Three-stage build with a distroless final stage:
Distroless's default ENTRYPOINT is ["/nodejs/bin/node"], but the OpenChoreo Helm chart passes args: ["node",
"packages/backend", ...]. To keep that working without requiring a sibling chart change (which ideally should be done regardless, as the chart should be agnostic to image behaviour), the final stage sets ENTRYPOINT [] + ENV
PATH=/nodejs/bin:$PATH so the chart's literal node resolves via PATH. CMD ["node", "packages/backend"] preserves standalone docker run behavior.
Image base pinned by digest in ARG so both the build base and runtime base are reproducible. Images are based on official ones and Google distroless images to align with the rest of OpenChoreo, but they could be swapped by Chainguard, Docker Hardened Images or any other undistro / distroless and should work without much trouble.
User stories
Release note
packages/backend/Dockerfile: shrink from ~1.6 GB to ~855 MB, hardened by switching to a distroless image
Documentation
N/A. Only affects Dockerfile and .dockerignore, no further changes, documentation is self-contained within comments.
Training
N/A
Certification
N/A
Marketing
N/A
Automation tests
N/A
Security checks
Samples
N/A
Related PRs
N/A
Migrations (if applicable)
N/A
Test environment
Learning
Backstage's yarn workspaces focus --all --production is sensitive to BuildKit cache mount paths. Mounting /home/node/.yarn (yarn berry's global cache root) leaks install-state between stages and short-circuits the focus install. Keeping the upstream mount path /app/.yarn/cache (or the inherited /home/node/.cache/yarn) avoids this.
The "conservative" find ... -prune patterns aggressively used by node-prune collide with several packages that use generic directory names (yaml/dist/doc/, @backstage/plugin-app-backend/dist/lib/assets/) at runtime. Final prune list intentionally excludes doc, docs, assets, images, media, website, *.ts, .tsx, tsconfig.json, LICENSE and *.d.ts files, which in particular are read by Backstage's config-loader at startup to validate app-config.yaml.
References used:
Summary by CodeRabbit