For Go with no cgo use the static image, for Node.js, Java and Python use the matching runtime image, and prefer the nonroot tag for all of them. Distroless images contain only your app and its runtime dependencies, with no package manager or shell, so entrypoints must use exec form.
What the project publishes
The distroless project lists current images built on Debian 13. Based on its README, the families are static, base, base-nossl and cc for compiled code, java-base plus java17, java21 and java25 for Java, nodejs22, nodejs24 and nodejs26 for Node.js, and python3 for Python. Each family offers tags latest, nonroot, debug and debug-nonroot.
| Your service | Image family | Notes |
|---|---|---|
| Go without cgo | static | Includes certificates and tzdata |
| Go with cgo, Rust, C | base, or cc | Adds glibc, base also adds libssl |
| Node.js | nodejs plus major version | Pick a version you support |
| Java | java plus 17, 21 or 25 | JRE style runtime, no shell |
| Python | python3 | Check which Python minor it carries |
Architecture support varies by image, so confirm the list for your platform in the README table before you commit.
The tag choices
- latest: the default tag. The README does not promise a non-root user, so treat it as root unless you check with the id command.
- nonroot: the variant intended to run as a non-root user. Use this by default and verify it.
- debug: adds a busybox shell, for troubleshooting.
- debug-nonroot: debug with a non-root user.
The project says that if an image already has a tag such as the nonroot one, you use the debug tag with a matching prefix to get a shell. Keep debug images out of production.
Three things that surprise people
- No shell means ENTRYPOINT must be in exec form. The README shows that a string form entrypoint does not work, while a JSON array does.
- Static, base and cc images have an empty entrypoint by default, while the language images have a language specific default, so your CMD differs by family.
- Debugging uses a different approach. See debugging a distroless container with ephemeral containers rather than adding a shell to the image.
Verify before you build on them
The README states that all distroless images are signed with cosign using keyless signing, and recommends verifying any distroless image before you build on it, with the issuer and identity the project documents. It also says the images track upstream Debian releases and open update pull requests automatically. That is a good sign, but your image does not change until you rebuild.
Example for Node.js
FROM node:24-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
FROM gcr.io/distroless/nodejs24-debian13:nonroot
WORKDIR /app
COPY --from=build /app /app
CMD ["server.js"]
For the language images the entrypoint is already the runtime, so CMD carries the script. Check the language README for the exact usage.
Where Safeguard fits
A distroless base shrinks operating system findings, but your dependencies remain. Safeguard scans them, builds an SBOM and uses reachability analysis to rank what matters. Policies can gate pull requests. Try the free scan.
Quick check
Is distroless the same as scratch?
No. Scratch is empty. Distroless images include a minimal Linux base with items such as certificates, and language images include the runtime.
Do I need the debug tag in production?
No. Use it temporarily in a non-production environment, or use ephemeral debug containers in your cluster.
Sources
Last reviewed: 19 October 2026.