agentsclimarketplace

Dockerfile best practices

Skill VersoXBT/claude-initial-setup/skills/docker/dockerfile-best-practices

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 dockerfile-best-practices

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 writing production-ready Dockerfiles with multi-stage builds, layer caching, security hardening, and optimized image sizes. Use when the user creates a Dockerfile, asks about Docker image optimization, mentions container security, or needs help with build performance. Trigger whenever Docker or container packaging is discussed.

SKILL.md

4.7 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it

Dockerfile Best Practices

Write secure, efficient, and maintainable Dockerfiles that produce minimal production images with proper caching, non-root users, and health checks.

When to Use

  • User creates or modifies a Dockerfile
  • User asks about reducing Docker image size
  • User mentions container security or hardening
  • User has slow Docker builds or cache invalidation issues
  • User asks about COPY vs ADD or layer ordering

Core Patterns

Multi-Stage Builds

Separate build dependencies from runtime to minimize final image size.

# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
COPY src/ src/
COPY tsconfig.json ./
RUN npm run build

# Stage 2: Production
FROM node:20-alpine AS production
WORKDIR /app
RUN addgroup -g 1001 appgroup && \
    adduser -u 1001 -G appgroup -s /bin/sh -D appuser
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]

Layer Caching Optimization

Order instructions from least to most frequently changed. Copy dependency manifests before source code so dependency installs are cached across builds.

FROM python:3.12-slim

WORKDIR /app

# System deps change rarely -- cache this layer
RUN apt-get update && \
    apt-get install -y --no-install-recommends libpq-dev && \
    rm -rf /var/lib/apt/lists/*

# Dependencies change occasionally -- cache this layer
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# Source code changes frequently -- last layer
COPY . .

CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0"]

Non-Root User

Never run containers as root in production. Create a dedicated user with minimal permissions.

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

FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /server /server
USER 65534:65534
ENTRYPOINT ["/server"]

.dockerignore

Always include a .dockerignore to prevent sending unnecessary files to the build context.

.git
.github
node_modules
dist
*.md
.env*
.vscode
.idea
docker-compose*.yml
Dockerfile*
coverage
__pycache__
*.pyc
.pytest_cache

Health Checks

Define health checks in the Dockerfile so orchestrators can monitor container health.

# HTTP health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -f http://localhost:8080/healthz || exit 1

# TCP health check (when curl is unavailable)
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD nc -z localhost 8080 || exit 1

Anti-Patterns

  • Using latest tag: Always pin base image versions (node:20.11-alpine, not node:latest). Unpinned tags cause non-reproducible builds.
  • Running as root: Never omit the USER instruction. Root in a container is root on the host if the container escapes.
  • Using ADD instead of COPY: ADD auto-extracts archives and fetches URLs, which is unexpected. Use COPY for local files; use curl or wget explicitly for remote files.
  • Installing dev dependencies in production: Use npm ci --omit=dev or pip install --no-dev in the final stage.
  • Single-stage builds: Shipping compilers, build tools, and source code in production images wastes space and expands the attack surface.
  • Not cleaning up apt/apk cache: Always add rm -rf /var/lib/apt/lists/* after apt-get install or use --no-cache with apk add.

Quick Reference

PracticeDoDon't
Base imagenode:20-alpinenode:latest
Copy filesCOPY . .ADD . .
UserUSER 1001(run as root)
Install depsRUN npm ciRUN npm install
Layer orderdeps before sourcesource before deps
Secrets--mount=type=secretCOPY .env .
HealthHEALTHCHECK CMD ...(no health check)
Cacherm -rf /var/lib/apt/lists/*(leave cache)

What ships with it

Read from the repository

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

Gives 0 of the 12 instructions most performance cost skills give in ~1.2k tokens

Counted across 803 of the 1,058 authors here whose files we hold, read 2026-08-07

  • Keep skill files under 500 lines or tokensin 82 of 803, across 16 files
  • Use imperative form in instructionsin 80 of 803, across 9 files
  • Draft assertions while test runs are in progressin 75 of 803, across 9 files
  • Create two to three realistic test promptsin 74 of 803, across 9 files
  • Write skill descriptions to be pushyin 72 of 803, across 7 files
  • Save test cases to evals JSONin 72 of 803, across 6 files
  • Ask questions about edge cases and input formatsin 72 of 803, across 7 files
  • Save timing data immediately when runs completein 70 of 803, across 5 files
  • Include all trigger conditions in the skill descriptionin 69 of 803, across 3 files
  • Launch all test runs in a single turn or simultaneouslyin 69 of 803, across 3 files
  • Capture intent before writing a skillin 67 of 803, across 1 file
  • Import directly instead of barrel filesin 52 of 803, across 15 files

Said here and by no other author read

  • create a non-root user
  • define a health check
  • use COPY instead of ADD
  • install production dependencies only
  • clean package manager caches after installing

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

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.