Skip to content

ref(build): Use DHI static base image and statically link libstdc++#6131

Draft
oioki wants to merge 2 commits into
masterfrom
atarasov/ref/dhi-static-base-image
Draft

ref(build): Use DHI static base image and statically link libstdc++#6131
oioki wants to merge 2 commits into
masterfrom
atarasov/ref/dhi-static-base-image

Conversation

@oioki

@oioki oioki commented Jun 24, 2026

Copy link
Copy Markdown
Member

Switch the release container base image from gcr.io/distroless/cc-debian13 to the mirrored Docker Hardened Image us-docker.pkg.dev/sentryio/dhi-mirror/static:20250419-glibc-debian13.

What

  • Dockerfile.release: new base image, and the builder stage is dropped entirely. The static image has no shell (no busybox), so the /work and /etc/relay volume directories are seeded from the image's own pre-existing, empty, nonroot-owned (uid/gid 65532) /home/nonroot directory via COPY --from. No external builder image is needed.
  • relay-crash/build.rs: link libstdc++ statically on Linux (static=stdc++).
  • build_binary.yml: add g++ to the release build container so libstdc++.a is present.

Why

Unlike the distroless cc image, the static image does not ship libstdc++.so.6. relay-crash depends on it because sentry-native/breakpad is C++ (cargo:rustc-link-lib=dylib=stdc++), so the dynamically-linked binary fails to start on the static image with:

/bin/relay: error while loading shared libraries: libstdc++.so.6: cannot open shared object file

Linking the C++ runtime statically keeps the minimal static base usable. relay is a leaf binary and sentry-native is already fully static, so the usual multi-runtime hazard of static libstdc++ does not apply here.

Two non-obvious details worth a careful look:

  • The static=stdc++ directive must be emitted after the breakpad_client/sentry static libs — static archive linking is order-sensitive (the old dylib position only worked because dynamic linking ignores order).
  • static=stdc++ makes rustc resolve libstdc++.a itself, but it lives in a gcc-internal, arch/version-specific directory not on rustc's default search path. The build script queries cc -print-file-name=libstdc++.a to add it.

Verification

Built relay with --features crash-handler in an ubuntu:20.04 container (matching the release toolchain). readelf -d on the result shows no libstdc++.so.6 in NEEDED (only libc, libm, libgcc_s, libpthread, libdl, ld-linux), all of which are present in the static image, and ~85 C++ symbols are statically baked in. Verified on arm64 locally; CI covers x86_64 via the same code path.

Supersedes #6117.

oioki and others added 2 commits June 24, 2026 13:44
Switch the release container from gcr.io/distroless/cc-debian13 to the
mirrored Docker Hardened Image us-docker.pkg.dev/sentryio/dhi-mirror/static.
The static image has no shell, so the volume dirs are seeded from its own
pre-existing nonroot-owned /home/nonroot instead of a busybox mkdir stage.

Unlike the distroless "cc" image, the static image does not ship
libstdc++.so.6, which relay-crash depends on (sentry-native/breakpad is
C++). Link the C++ standard library statically on Linux so the binary runs
on the minimal image. This must come after the breakpad/sentry static libs
(static archive linking is order-sensitive), and needs libstdc++.a's
gcc-internal directory on the link search path, queried via
`cc -print-file-name`. Add g++ to the release build container so that
archive is present.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
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