agentsclimarketplace

Multi stage builds

Skill VersoXBT/claude-initial-setup/skills/docker/multi-stage-builds

75 skills, 14 agents, 15 commands for Claude Code. Plug-and-play starter kit covering TypeScript, Python, Go, Rust, React, Next.js, FastAPI, Django, Docker, CI/CD, security, testing, and more. Cross-AI support for Cursor, Copilot, and Codex.

Install
npx -y skills add VersoXBT/claude-initial-setup --skill multi-stage-builds

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Guide for Docker multi-stage builds with builder patterns, distroless and alpine base images, cache mounts, and build args. Use when the user needs to optimize Docker image size, separate build from runtime dependencies, or improve build performance. Trigger when the user mentions multi-stage, distroless, slim images, or Docker build optimization.

SKILL.md

5.9 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it

Multi-Stage Builds

Use multi-stage Docker builds to produce minimal, secure production images by separating build-time tooling from runtime dependencies.

When to Use

  • User needs to reduce Docker image size
  • User ships compilers or build tools in production images
  • User asks about distroless or alpine base images
  • User wants faster Docker builds with cache mounts
  • User needs different images for dev, test, and production

Core Patterns

Node.js Builder Pattern

Separate TypeScript compilation and dependency installation from the runtime image.

# ---------- Stage 1: Install dependencies ----------
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# ---------- Stage 2: Build ----------
FROM deps AS builder
COPY tsconfig.json ./
COPY src/ src/
RUN npm run build && npm prune --omit=dev

# ---------- Stage 3: Production ----------
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["dist/index.js"]

Result: ~150MB image instead of ~1GB with full Node.js + dev dependencies.

Go Static Binary

Go compiles to a single static binary, making scratch or distroless ideal.

FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -ldflags="-s -w" -o /server ./cmd/server

FROM gcr.io/distroless/static-debian12
COPY --from=builder /server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]

Result: ~10-20MB image with zero OS packages and no shell for attackers to exploit.

Python with Virtual Environment

Isolate Python dependencies in a virtualenv, then copy only the venv to the runtime image.

FROM python:3.12-slim AS builder
WORKDIR /app
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

FROM python:3.12-slim
WORKDIR /app
RUN groupadd -r app && useradd -r -g app app
COPY --from=builder /opt/venv /opt/venv
COPY --from=builder /app /app
ENV PATH="/opt/venv/bin:$PATH"
USER app
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Cache Mounts for Faster Builds

Use BuildKit cache mounts to persist package manager caches across builds, avoiding repeated downloads.

FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \
    npm ci
COPY . .
RUN npm run build

FROM rust:1.77-alpine AS rust-builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src/ src/
RUN --mount=type=cache,target=/usr/local/cargo/registry \
    --mount=type=cache,target=/app/target \
    cargo build --release && \
    cp target/release/myapp /usr/local/bin/myapp

Build Args for Conditional Stages

Use build args to customize builds without separate Dockerfiles.

ARG BUILD_ENV=production

FROM node:20-alpine AS base
WORKDIR /app
COPY package.json package-lock.json ./

FROM base AS deps-production
RUN npm ci --omit=dev

FROM base AS deps-development
RUN npm ci

FROM deps-${BUILD_ENV} AS deps

FROM node:20-alpine AS final
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

Build with: docker build --build-arg BUILD_ENV=development -t myapp:dev .

Target-Based Development Workflow

Use named stages with --target for different environments from a single Dockerfile.

FROM node:20-alpine AS base
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM base AS development
COPY . .
CMD ["npm", "run", "dev"]

FROM base AS test
COPY . .
RUN npm run lint && npm test

FROM base AS builder
COPY . .
RUN npm run build && npm prune --omit=dev

FROM gcr.io/distroless/nodejs20-debian12 AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["dist/index.js"]
docker build --target development -t myapp:dev .
docker build --target test -t myapp:test .
docker build --target production -t myapp:prod .

Anti-Patterns

  • Copying build tools into production: Never include compilers, package managers, or dev headers in the final stage. They waste space and increase attack surface.
  • Using ubuntu or debian for runtime: Prefer alpine, slim, distroless, or scratch. A full Debian base adds 100-200MB of unnecessary packages.
  • Not separating dependency install from code copy: If you COPY everything before npm ci, every source code change invalidates the dependency cache.
  • Ignoring --mount=type=cache: Without cache mounts, every build re-downloads all dependencies from scratch. Enable BuildKit and use cache mounts.
  • Single Dockerfile per environment: Use --target and build args instead of maintaining separate Dockerfiles for dev, test, and prod.

Quick Reference

Base ImageSizeShellUse Case
scratch0 MBNoGo static binaries
distroless/static~2 MBNoStatic binaries, max security
distroless/cc~20 MBNoC/C++ apps needing libc
distroless/nodejs20~130 MBNoNode.js production
alpine~7 MBYesWhen you need a shell
debian-slim~80 MBYesWhen you need apt packages
# Enable BuildKit (required for cache mounts)
export DOCKER_BUILDKIT=1

# Build specific target
docker build --target production -t myapp:prod .

# Check final image size
docker images myapp:prod

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 327,132. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.