Your application has zero vulnerabilities. Your base image has 142. Most container CVEs come from OS packages in the base image that your application never uses. Wolfi eliminates them.
The Base Image Problem
# Scan a standard Node.js image
trivy image node:20
# Total: 142 vulnerabilities (2 Critical, 10 High)
# Scan an Alpine Node.js image
trivy image node:20-alpine
# Total: 3 vulnerabilities (0 Critical, 1 High)
# Scan a Chainguard Node.js image
trivy image cgr.dev/chainguard/node:latest
# Total: 0 vulnerabilitiesStandard images include shells, package managers, compilers, and system utilities. Attackers use these tools after gaining initial access. If they are not in the image, they cannot be exploited.
What Wolfi Is
Wolfi is a Linux distribution built specifically for containers:
- Minimal: Only packages your application needs
- No shell by default: No
bash,sh, orashunless explicitly added - No package manager in runtime:
apkavailable in build stage only - Rolling releases: Packages updated continuously, CVEs patched within hours
- SBOM built-in: Every package includes a Software Bill of Materials
- Signed packages: Cryptographic signatures on all packages
Master this topic with hands-on labs
Go beyond reading — build real projects in sandboxed environments with expert video guidance.
Browse Courses →Chainguard Images
Chainguard builds production images using Wolfi:
# Instead of this:
FROM node:20-slim
# Use this:
FROM cgr.dev/chainguard/node:latestAvailable for: Node.js, Python, Go, Java, Rust, Ruby, PHP, nginx, PostgreSQL, Redis, and 100+ other images.
Building with Wolfi
Multi-Stage Build
# Build stage: has tools
FROM cgr.dev/chainguard/node:latest-dev AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
# Runtime stage: minimal
FROM cgr.dev/chainguard/node:latest
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["dist/server.js"]The -dev variant includes a shell and package manager for building. The runtime variant has neither.
Custom Images with apko
Build custom Wolfi-based images declaratively:
# apko.yaml
contents:
repositories:
- https://packages.wolfi.dev/os
packages:
- wolfi-baselayout
- python-3.12
- py3-pip
- ca-certificates-bundle
accounts:
groups:
- groupname: app
gid: 1000
users:
- username: app
uid: 1000
run-as: 1000
entrypoint:
command: /usr/bin/python3
archs:
- x86_64
- aarch64apko build apko.yaml myorg/python:latest image.tar
docker load < image.tarSecurity Comparison
| Image | CVEs (typical) | Size | Shell | Package Manager |
|---|---|---|---|---|
| ubuntu:22.04 | 30-80 | 77MB | Yes | apt |
| debian:12-slim | 20-50 | 74MB | Yes | apt |
| alpine:3.19 | 0-5 | 7MB | Yes | apk |
| cgr.dev/chainguard/static | 0 | 2MB | No | No |
| cgr.dev/chainguard/node | 0 | 50MB | No | No |
Get weekly IT automation tips
Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.
Subscribe Free →Debugging Distroless Containers
Without a shell, you cannot exec into the container. Use these alternatives:
# Ephemeral debug container (Kubernetes 1.23+)
kubectl debug -it pod/order-api --image=busybox --target=order-api
# Or use the -dev variant temporarily
# Change image to cgr.dev/chainguard/node:latest-dev
# Shell in, debug, switch back to production imageMigration Path
- Start with scanning: Know your current CVE count
- Switch non-critical services first: Internal tools, batch jobs
- Use multi-stage builds: Build with
-dev, run with minimal - Update CI to scan: Fail builds if CVEs appear
- Gradually migrate critical services: Verify behavior in staging
Do not switch everything at once. Start with one service, verify it works, then expand.
When to Use Distroless
Always use distroless for: - Production workloads exposed to the internet - Services handling sensitive data - Container images stored in public registries - Compliance environments requiring minimal attack surface
Keep a shell for:
- Development environments
- Debug/troubleshooting images (use -dev variants)
- Legacy applications that shell out to system commands
---
Ready to go deeper? Master container security with hands-on courses at CopyPasteLearn.
Ready to learn by doing?
Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
Sigstore Container Image Signing
Sigstore provides keyless signing for container images and software artifacts. Learn how to sign images with Cosign, verify signatures in Kubernetes.
Cosign Container Image Signing
Cosign signs and verifies container images using keyless signing with Sigstore. Learn how to sign images in CI/CD, verify signatures before deployment.
Chainguard Enforce Supply Chain
Chainguard Enforce validates container supply chain integrity in Kubernetes using SLSA provenance, SBOMs, and image signatures. Learn how to enforce supply.
Woodpecker CI Self-Hosted Pipelines
Woodpecker CI is a lightweight, container-native CI/CD system you can self-host. Learn how Woodpecker compares to Drone, GitHub Actions, and GitLab CI.
YAML for DevOps Engineers
Master YAML for DevOps configuration. Scalars, lists, maps, anchors, multi-line strings, and common pitfalls to avoid in pipelines.
YAML Syntax Guide for DevOps
Master YAML syntax for DevOps tools. Scalars, lists, maps, anchors, multi-line strings, and common gotchas with pipeline examples.
Explore topics
Browse more articles on the topics covered here.