skills/sarpit/agent-skills/dockerfile-best-practices

dockerfile-best-practices

Installation
SKILL.md

Dockerfile Best Practices

Apply these rules when writing, reviewing, or optimizing any Dockerfile.

Base Images

  • Use minimal base images: alpine, slim, distroless, or scratch
  • Compiled languages (Go, Rust): use scratch images
  • Interpreted languages (Node.js, Python): use alpine or slim (runtime needed)
  • Always use multistage builds to separate build-time and runtime dependencies

Image Optimization

Layer Caching

Order layers from least-changing to most-changing:

Base image → Dependency files → Install dependencies → Config → Source code

Never copy source code before installing dependencies — a code change would invalidate the dependency cache.

Reducing Image Size

  • Combine RUN instructions to reduce layers
  • Be explicit with COPY targets instead of COPY . .
  • Install only production dependencies in the runtime stage

Security

  • Never run as root. Create a dedicated user/group with UID/GID > 10000
  • Pin image versions. Never use latest
  • Use official or verified images only
  • No secrets in images. No API keys, passwords, or config files with credentials
  • No sudo in containers
  • Use COPY over ADD to prevent fetching unknown URLs or extracting archives
  • No debugging tools. Do not install curl, wget, vim, or netstat
  • Executables owned by root, run by non-root user. Prevents an attacker from modifying binaries to persist access

Maintainability

  • Sort multi-line package installs alphabetically for cleaner diffs
  • Use WORKDIR to set the working directory
  • Use exec form for CMD: ["node", "app.js"] — shell form prevents signal forwarding (SIGTERM goes to /bin/sh, not the app)
  • Comment non-obvious decisions
  • Add OCI labels for metadata

Example: Node.js Multistage Dockerfile

# Build stage
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production
COPY src/ ./src/

# Runtime stage
FROM node:22-alpine
RUN addgroup -g 10001 appgroup && \
    adduser -u 10001 -G appgroup -D appuser
WORKDIR /app
COPY --from=builder --chown=root:root /app ./
USER appuser
EXPOSE 3000
CMD ["node", "src/index.js"]
Weekly Installs
2
First Seen
Feb 24, 2026
Installed on
opencode2
gemini-cli2
claude-code2
github-copilot2
codex2
kimi-cli2