56 results available
Sign in
Skills directory

multi-stage-dockerfile

github

·

Last changed
Not yet hardened

This version isn't hardened by Chainguard

No hardening report available.


SKILL.md

Your goal is to help me create efficient multi-stage Dockerfiles that follow best practices, resulting in smaller, more secure container images.

Multi-Stage Structure

  • Use a builder stage for compilation, dependency installation, and other build-time operations
  • Use a separate runtime stage that only includes what's needed to run the application
  • Copy only the necessary artifacts from the builder stage to the runtime stage
  • Use meaningful stage names with the AS keyword (e.g., FROM node:18 AS builder — replace node:18 with a digest-pinned reference in production)
  • Place stages in logical order: dependencies → build → test → runtime

Base Images

  • Start with official, minimal base images when possible
  • Specify exact version tags as a human-readable label (e.g., python:3.11-slim not just python), but pin base images by immutable digest for production and CI builds:
    FROM python:3.11-slim@sha256:<digest>
    Tags are mutable and can be silently repointed. To obtain the digest:
    docker pull python:3.11-slim
    docker inspect python:3.11-slim --format '{{index .RepoDigests 0}}'
    Use tools such as crane digest or Renovate's digest pinning to keep digests current.
  • Consider distroless images for runtime stages where appropriate
  • Use Alpine-based images for smaller footprints when compatible with your application
  • Ensure the runtime image has the minimal necessary dependencies

Layer Optimization

  • Organize commands to maximize layer caching
  • Place commands that change frequently (like code changes) after commands that change less frequently (like dependency installation)
  • Use .dockerignore to prevent unnecessary files from being included in the build context
  • Combine related RUN commands with && to reduce layer count
  • Consider using COPY --chown to set permissions in one step

Security Practices

  • Avoid running containers as root - use USER instruction to specify a non-root user
  • Remove build tools and unnecessary packages from the final image
  • Scan the final image for vulnerabilities
  • Set restrictive file permissions
  • Use multi-stage builds to avoid including build secrets in the final image
  • Never pass secrets via ARG or ENV — values persist in image layer history and are visible via docker history. Use BuildKit secret mounts for any credential needed only at build time:
    RUN --mount=type=secret,id=token,target=/run/secrets/token \
        some-command --token-file /run/secrets/token
    Invoke with: docker build --secret id=token,src=./token.txt .

Performance Considerations

  • Use build arguments (ARG) only for non-secret configuration that varies between environments (e.g., target architecture, version numbers). ARG values are stored in image layer history and are visible via docker history — never pass tokens, passwords, or API keys as build arguments (see Security Practices for the correct alternative).
  • Leverage build cache efficiently by ordering layers from least to most frequently changing
  • Consider parallelization in build steps when possible
  • Set appropriate environment variables like NODE_ENV=production to optimize runtime behavior
  • Use appropriate healthchecks for the application type with the HEALTHCHECK instruction

Install

Need this version hardened?

Harden your own skills

Bring Chainguard's hardening pipeline to your first-party skills — custom rulesets, automated remediation, full audit trail.

Provenance

Upstream source

—

Upstream commit1c67e92cd20c7f9e9df117b6ca545707af41faf7
OCI reference

—

License

MIT

Files

HARDENING.md

LICENSE

SKILL.md


The trusted source for open source

Talk to an expert
PrivacyTerms

Product

Chainguard ContainersChainguard LibrariesChainguard VMsChainguard OS PackagesChainguard ActionsChainguard Agent SkillsIntegrationsPricing
© 2026 Chainguard, Inc. All Rights Reserved.
Chainguard® and the Chainguard logo are registered trademarks of Chainguard, Inc. in the United States and/or other countries.
The other respective trademarks mentioned on this page are owned by the respective companies and use of them does not imply any affiliation or endorsement.