Repository navigation
Slim the Docker image: multi-stage build with a slim runtime - #58
Merged
Merged
Conversation
Owner
Author
|
Update: the new Dockerfile has now been built and run-verified locally (the PR description's "Docker isn't available in my environment" caveat no longer applies). Setup, for the record: this sandbox had no container runtime, so I installed Podman. Registry pulls from Go-based tooling are blocked here (the egress proxy drops Go's TLS fingerprint), so the base images were fetched with a curl-based OCI puller and loaded into Podman; the build ran with the vfs storage driver and chroot isolation (the VM also lacks /dev/fuse and namespace privileges). The only build-invocation accommodation was pointing cargo at this sandbox's proxy CA bundle — the Dockerfile itself is byte-for-byte the one in this PR; CI won't need any of that. Results:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The image was over 300MB because the Dockerfile was a single stage on
rust:latest: it built the app inside the image and then ran it from that same image, so the published image carried the entire Rust toolchain, the cargo registry cache, and all intermediate build artifacts.The change (Dockerfile only)
Two stages:
rust:1-bookworm): the usualcargo build --release, plusstripon the binary.debian:bookworm-slim): only three things — the stripped binary (/usr/local/bin/brunnylol),static/, andca-certificates(the AI feature makes outbound HTTPS calls). Same env (BRUNNYLOL_PORT,BRUNNYLOL_DB=/data/...), same exposed port, so the existing run/compose setup is untouched.Two details that matter:
static/is copied from the builder stage:build.rsgenerates the favicon PNGs into it during the build, and those are gitignored, so the build-context copy ofstatic/in a fresh CI checkout doesn't have them.Expected size
Measured locally: the release binary is 15.3MB (11.4MB stripped) and links only glibc basics — SQLite is compiled in — and
static/is 100KB. On bookworm-slim (~74MB) the final image should land around 85MB on disk / ~40MB pulled, down from 300MB+.Verification, honestly scoped
Docker isn't available in my environment, so I could not build the image itself — this PR's Docker workflow run is the end-to-end proof, and it should be green before merging. What I did verify locally:
static/, run with the container's env vars — it serves/, the CSS, both favicon files, and the descriptor (all 200s). Everything else the app needs (templates, migrations,commands.yml, API docs) is compiled into the binary via Askama/include_str!, confirmed by auditing the source.lddon the binary: libc/libm/libgcc only.Rollback is a plain revert of this one file.