Skip to content

Reduce Docker image attack surface: switch from debian to distroless/static #3540

@derrix060

Description

@derrix060

Summary

The production Docker image currently uses debian:bookworm-slim with several runtime packages that increase CVE surface. Propose switching to a minimal base image.

Current state

FROM debian:bookworm-slim AS final
RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates curl gawk grep libjemalloc-dev libjemalloc2 \
    && ...

Issues:

  • debian:bookworm-slim ships ~80+ packages with potential CVEs
  • curl, gawk, grep are runtime dependencies — are they needed? K8s readiness probes use kubelet HTTP checks, not in-container curl
  • libjemalloc-dev is a development package (headers + static lib) — only libjemalloc2 is needed at runtime
  • Trivy scans flag CVEs in OS packages that aren't related to Juno

Proposal

Option A: gcr.io/distroless/cc-debian12 (recommended)

  • Has libc + libgcc (needed for CGO/Rust FFI)
  • No shell, no package manager, no curl/gawk/grep
  • Copy only libjemalloc.so.2 from builder
  • ~20MB base vs ~80MB for debian-slim
FROM gcr.io/distroless/cc-debian12 AS final
COPY --from=builder /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 /usr/lib/x86_64-linux-gnu/
COPY --from=builder /app/build/juno /usr/local/bin/
ENTRYPOINT ["juno"]

Option B: Static build + scratch

  • Statically link libjemalloc and Rust libs
  • Zero OS packages, zero CVEs
  • Requires build changes (CGO_ENABLED=1 with -linkmode external -extldflags "-static" and musl)
  • More complex but the gold standard

Option C: Alpine

  • Smaller than debian, musl-based
  • Still has a package manager and OS packages (CVE surface)
  • May have musl compatibility issues with Rust FFI

Questions

  1. Are curl, gawk, grep used at runtime? (init containers, health checks, scripts?)
  2. Is jemalloc required or optional? (can it fall back to default allocator?)
  3. Any objection to removing shell access from the production image?

Benefits

  • Eliminates most/all OS-level CVEs from Trivy scans
  • Smaller image size (~20MB savings)
  • Reduced attack surface (no shell = no shell injection)
  • No .trivyignore needed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions