← Back to PRs

#19836: build: multi-stage Dockerfile reduces image size by ~3GB (4.7GB → 1.6GB)

by dbachelder open 2026-02-18 07:08 View on GitHub →
docker size: S
## Summary The current Dockerfile produces a ~4.7GB image (linux/amd64) due to three issues: 1. **`chown -R node:node /app`** duplicates the entire `/app` directory as a new layer (~1.6GB) just to change file ownership 2. **Bun** is installed for build scripts but carried into the final image (~100MB runtime) 3. **Dev dependencies** are not pruned after build This PR converts to a multi-stage build: - **Builder stage**: installs bun, runs pnpm install, builds, then prunes dev deps - **Runtime stage**: uses `node:22-bookworm-slim` (smaller base, digest-pinned) and `COPY --chown=node:node` from builder — sets ownership during copy with zero layer overhead Also updates `docker-image-digests.test.ts` to validate all `FROM` lines in multi-stage Dockerfiles (not just the first) and allow the `AS <alias>` suffix. ## Results | | Before | After | Savings | |---|--------|-------|---------| | Image size (amd64) | ~4.7 GB | ~1.6 GB | **-3.1 GB (65%)** | Tested locally — gateway starts and serves WebSocket connections correctly. ## Test plan - [x] Build image locally with `docker build --platform linux/amd64` - [x] Verify `node openclaw.mjs --version` returns correct version - [x] Verify gateway starts with `--allow-unconfigured --bind lan` - [x] Verify TCP connectivity on port 18789 - [x] Both `FROM` lines pinned to sha256 digests - [x] Updated digest test passes locally - [ ] CI pipeline passes 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Most Similar PRs