Skip to content

feat(docker): Build a distroless image variant - #819

Draft
oioki wants to merge 2 commits into
mainfrom
feat/docker-distroless-image
Draft

oioki wants to merge 2 commits into
mainfrom
feat/docker-distroless-image

Conversation

@oioki

@oioki oioki commented Oct 15, 2026

Copy link
Copy Markdown
Member

Add a taskbroker-distroless stage to the Dockerfile and publish it next to the current image:

  • ghcr.io/getsentry/taskbroker:<sha>-distroless and :nightly-distroless (amd64 + arm64)
  • <sha>-distroless in us-central1-docker.pkg.dev/sentryio/taskbroker/image and us-docker.pkg.dev/sentryio/taskbroker-mr/image

The debian stage stays last, so builds without --target produce the same image, and :nightly, :latest and self-hosted are unchanged. Nothing deploys the distroless image yet. The self-hosted e2e test now runs against both variants.

The base is the DHI static glibc Debian 13 image from the AR mirror, the same one relay uses. It has no shell or package manager and runs as nonroot (uid 65532). Brokers in k8s already use gRPC probes and set runAsUser: 1000 with fsGroup, so switching a region only needs the image tag.

This also changes the current image. The first commit builds rdkafka with ssl-vendored and libz-static (like getsentry/relay#4978), so the binary only needs glibc. The debian image runs the same binary, so production moves from the system libssl3 to OpenSSL 3.6 from openssl-src. Brokers use sasl_plaintext with SCRAM, so this affects SASL hashing, not certificate handling. OpenSSL updates now come through openssl-src bumps instead of the base image. I can split this commit into its own PR if we'd rather deploy it alone first.

The distroless stage copies a prepared /opt onto /: the base already has a root-owned /opt and no shell to fix that, and taskbroker reads ./VERSION and defaults to ./taskbroker-inflight.sqlite relative to it. The distroless builds read the per-architecture build cache from #817 but don't export it, so they don't overwrite the default build's cache index.

trivy, local arm64 builds of this branch:

Image OS vulns Size (gzip)
debian (current) 1208 (1 critical, 103 high) 113 MB
distroless 23 (medium/low, glibc) 60 MB

Other bases considered: gcr.io/distroless/cc-debian13 ships libssl3 and zlib, so it needs no Cargo change, but it isn't the DHI base the rest of Sentry uses. A fully static musl build would use the musl allocator, which is slow under multithreaded load.

🤖 Generated with Claude Code

oioki and others added 2 commits October 15, 2026 20:35
Build rdkafka with ssl-vendored and libz-static, so the taskbroker
binary only needs glibc at runtime. This lets it run on a glibc-only
distroless base, like relay did in getsentry/relay#4978.

The debian image runs the same binary, so it now uses OpenSSL 3.6
from openssl-src instead of the system libssl3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a taskbroker-distroless stage on the DHI static glibc Debian 13
base and publish it next to the current image as <sha>-distroless and
nightly-distroless on GHCR, and <sha>-distroless in both production
registries. The debian stage stays last, so builds without --target
produce the same image as today.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oioki oioki added the do not merge Don't merge label Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge Don't merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant