Skip to content

ci: single multi-target Dockerfile — slim base-nossl release image, byte-identical binary#64

Merged
wadahiro merged 2 commits into
mainfrom
ci/distroless-base-nossl
Jun 13, 2026
Merged

ci: single multi-target Dockerfile — slim base-nossl release image, byte-identical binary#64
wadahiro merged 2 commits into
mainfrom
ci/distroless-base-nossl

Conversation

@wadahiro

@wadahiro wadahiro commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Consolidates the container image story into one Dockerfile and slims the published image.

One multi-target Dockerfile (no more Dockerfile.release)

Runtime settings (user/workdir/entrypoint/cmd/expose) live in a single runtime stage so they can't drift between two files. Two final targets:

  • source (default) — compiles from source (rust:1.96-bookworm) and runs on distroless/cc (plain cargo binaries dynamically link libgcc_s, which only cc ships). Used by docker build ., docker-compose, and the CI build check — local builds still compile from source, no extra steps.
  • prebuilt — COPYs the exact prebuilt release binary onto distroless/base-nossl (the cargo-zigbuild release binaries link libgcc statically, so the smaller, OpenSSL-free base works). The published image is byte-identical to the released binary. release.yml builds it with --target prebuilt --build-arg RUNTIME=…base-nossl….

buildkit only builds the requested target's stages, so docker build . skips the prebuilt COPY bin/, and the release build skips the Rust compile. No fragile hand-copying of system libraries — both paths use official distroless images with matched libs.

Why base-nossl for the release image

scim-server serves plain HTTP (TLS is terminated at a proxy) and uses rustls for its only TLS (the PostgreSQL client), with no C++ deps. So OpenSSL + libstdc++ from cc are unnecessary → base-nossl is ~8–12MB smaller. Verified: the published v0.4.1 binary serves CRUD on base-nossl (51.5MB image).

Verified locally

  • source target builds and runs (scim-server 0.4.1).
  • prebuilt target builds from the v0.4.1 release binary and runs on base-nossl.

Note

ci:/build: change → does not trigger a release on its own. Ships on the next release (Release-As: 0.4.2).

🤖 Generated with Claude Code

…SSL/C++)

The release image used distroless/cc, which bundles OpenSSL (libssl3, ~8MB) and
the C++ runtime (libstdc++/libgomp). scim-server needs neither:
- it serves plain HTTP (TcpListener + axum::serve); TLS termination is expected
  at a reverse proxy (hence the X-Forwarded-* host resolution). No server TLS.
- the only TLS is the PostgreSQL client via sqlx + rustls (pure Rust, no OpenSSL).
- no C++ dependencies (SQLite is C, compiled into the binary).

Switch Dockerfile.release to distroless/base-nossl-debian13 — ~12MB smaller and
still has glibc + ca-certificates. Verified: the published v0.4.1 binary serves
ServiceProviderConfig and User CRUD on base-nossl.

The self-contained Dockerfile (dev/compose/CI) stays on distroless/cc: plain
cargo binaries dynamically link libgcc_s.so.1, which base-nossl omits. The
release binaries don't need it because cargo-zigbuild links libgcc statically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wadahiro wadahiro changed the title ci: slim release image to distroless/base-nossl (drop unused OpenSSL/C++) ci: single multi-target Dockerfile — slim base-nossl release image, byte-identical binary Jun 13, 2026
…ase)

Replace the two Dockerfiles with one multi-stage Dockerfile so the runtime
settings (user/workdir/entrypoint/cmd/expose) live in a single place and can't
drift:

- `source` target (default) — compiles from source on rust:1.96-bookworm and
  runs on distroless/cc (plain cargo binaries dynamically link libgcc_s, which
  only cc ships). Used by `docker build .`, docker-compose, and the CI check.
- `prebuilt` target — COPYs the prebuilt release binary onto base-nossl (the
  cargo-zigbuild binaries link libgcc statically, so the smaller base works).
  release.yml builds it with `--target prebuilt --build-arg
  RUNTIME=...base-nossl...`.

buildkit only builds the requested target's stages, so `docker build .` skips
the prebuilt stage's `COPY bin/` and the release build skips the Rust compile.
No fragile hand-copying of system libraries; both paths use official distroless
images with matched libs.

Verified: source target builds/runs; prebuilt target builds from the v0.4.1
binary and runs on base-nossl (51.5MB).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wadahiro wadahiro force-pushed the ci/distroless-base-nossl branch from 7259196 to 5426d57 Compare June 13, 2026 13:04
@wadahiro wadahiro merged commit ccd21b2 into main Jun 13, 2026
12 checks passed
@wadahiro wadahiro deleted the ci/distroless-base-nossl branch June 13, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant