Build secure container images with Wolfi runtime, non-root users, and multi-stage builds. Templates for Python/uv, Bun, Node.js/pnpm, Golang (static/CGO), and Rust (glibc/musl) with allocator optimization
How this skill is triggered — by the user, by Claude, or both
Slash command
/secure-container-build:secure-container-buildThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Build secure, minimal container images using security-hardened runtime images and multi-stage builds.
assets/Containerfile.bunassets/Containerfile.golangassets/Containerfile.golang-cgoassets/Containerfile.nodejsassets/Containerfile.python-uvassets/Containerfile.rustassets/Containerfile.rust-muslreferences/allocator-comparison.mdreferences/debugging-containers.mdreferences/dependency-management.mdreferences/security-best-practices.mdBuild secure, minimal container images using security-hardened runtime images and multi-stage builds.
Use Wolfi glibc-dynamic as the runtime base image:
# ARG for choosing runtime image tag
ARG RUNTIME_TAG=latest
FROM cgr.dev/chainguard/glibc-dynamic:${RUNTIME_TAG}
latest (default): Production - no shell, most securelatest-dev: Development - includes shell for debuggingpodman build --build-arg RUNTIME_TAG=latest-dev -t myapp:debug .
podman run -it myapp:debug sh # Can exec with shell
Always use multi-stage builds to minimize runtime image size:
Wolfi images use UID 65532 (nonroot user) by default:
# No need to create user, already exists in Wolfi
USER 65532:65532
# When copying files from builder, set ownership
COPY --from=builder --chown=65532:65532 /app /app
Wolfi images don't include tini. Copy it from builder:
# Copy tini from builder stage
COPY --from=builder /usr/bin/tini-static /usr/bin/tini
# Use as entrypoint for proper signal handling
ENTRYPOINT ["tini", "--"]
CMD ["your-app"]
Copy Containerfile template:
cp assets/Containerfile.python-uv ./Containerfile
Update application command:
CMD ["python", "your_app.py"] # Change to your entry point
Copy Containerfile template:
cp assets/Containerfile.bun ./Containerfile
Update runtime command:
CMD ["bun", "run", "start"] # Change to your script
Copy Containerfile template:
cp assets/Containerfile.nodejs ./Containerfile
Update entry point:
CMD ["node", "./dist/index.js"] # Change to your compiled output
First: Do you need CGO? (packages with C bindings)
Most Go projects don't need CGO. Quick test:
CGO_ENABLED=0 go build .
# Success → Use Containerfile.golang (static, recommended)
# Fails → Use Containerfile.golang-cgo (CGO)
Common CGO packages: mattn/go-sqlite3, git2go/git2go, h2non/bimg
Copy Containerfile template:
cp assets/Containerfile.golang ./Containerfile
Update binary name:
CMD ["/app/server"] # Change to your binary name
Copy CGO template:
cp assets/Containerfile.golang-cgo ./Containerfile
Default: Use glibc template (best compatibility)
Copy template:
cp assets/Containerfile.rust ./Containerfile
Update binary name:
CMD ["/app/server"] # Change to your binary name
Optional: Boost performance with mimalloc
Three allocator options (see comments in Containerfile):
Why mimalloc? Reduces memory usage by ~50% vs glibc malloc under load. See allocator comparison for details vs jemalloc/tcmalloc.
If you need the smallest possible image and have no C dependencies:
Copy musl template:
cp assets/Containerfile.rust-musl ./Containerfile
Warning: musl's allocator is 7-10x slower in multi-threaded workloads. You MUST add mimalloc to Cargo.toml (see Containerfile comments).
FROM docker.io/python:3-slim AS builder
Use official Python slim images for building Python applications with uv.
FROM docker.io/node:lts-slim AS builder
Use official Node.js LTS slim images for building Bun or Node.js applications.
FROM docker.io/golang:1 AS builder
Use official Golang images for building Go applications. Includes Go toolchain and gcc for CGO support.
FROM docker.io/rust:slim AS builder
Use official Rust slim images for building Rust applications. Includes rustc, cargo, and rustup for target management.
Use BuildKit cache mounts to speed up dependency installation:
# Python/uv
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# Bun
RUN bun install --frozen-lockfile
# pnpm
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
# Rust/cargo (both registry and target dir)
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
cargo build --release
FROM cgr.dev/chainguard/glibc-dynamic:${RUNTIME_TAG}
FROM cgr.dev/chainguard/static:${RUNTIME_TAG}
All Containerfile templates support both production and debug builds:
podman build -t myapp:latest .
cgr.dev/chainguard/glibc-dynamic:latestpodman build --build-arg RUNTIME_TAG=latest-dev -t myapp:debug .
cgr.dev/chainguard/glibc-dynamic:latest-devFor detailed debugging techniques, see references/debugging-containers.md.
For detailed information, consult these reference files:
references/security-best-practices.mdreferences/dependency-management.mdreferences/debugging-containers.mdreferences/allocator-comparison.mdFor GitHub Actions workflows to build multi-arch images, see the github-actions-container-build plugin which provides:
Build timeout:
Binary not found:
Container starts but exits immediately:
podman run -it myapp:debug shTest image locally:
podman run --rm -it "$IMAGE:$TAG"
Inspect built image:
podman inspect "$IMAGE:$TAG"
Check image size:
podman images "$IMAGE:$TAG"
npx claudepluginhub pigfoot/claude-code-hubs --plugin secure-container-buildBuilds container images on Google distroless base images to reduce attack surface by eliminating shells, package managers, and unnecessary OS utilities. Useful for security hardening and supply chain risk reduction.
Builds minimal container images using Google distroless bases to reduce attack surface by removing shells, package managers, and OS utilities for secure Docker/Kubernetes deployments.
Builds minimal container images using Google distroless bases to reduce attack surface by removing shells, package managers, and OS utilities for secure Docker/Kubernetes deployments.