docker-best-practices
Create production-grade Dockerfiles optimized for speed, security, and minimal size. Use when creating or reviewing Dockerfiles, docker-compose files, or when optimizing container images for Python, Node.js, or multi-runtime environments.
Best use case
docker-best-practices is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Create production-grade Dockerfiles optimized for speed, security, and minimal size. Use when creating or reviewing Dockerfiles, docker-compose files, or when optimizing container images for Python, Node.js, or multi-runtime environments.
Teams using docker-best-practices should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/docker-best-practices/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How docker-best-practices Compares
| Feature / Agent | docker-best-practices | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Create production-grade Dockerfiles optimized for speed, security, and minimal size. Use when creating or reviewing Dockerfiles, docker-compose files, or when optimizing container images for Python, Node.js, or multi-runtime environments.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Docker Best Practices
Production-grade Docker patterns optimized for fast builds, minimal size, and bulletproof security. Every container spins up in seconds, syncs efficiently, and never accumulates bloat.
## Core Principles
1. **Multi-stage builds** — Separate build dependencies from runtime
2. **Pinned versions** — Never use `:latest` tags
3. **Layer caching** — Order instructions from least to most frequently changing
4. **Minimal attack surface** — Distroless or slim base images, non-root users
5. **BuildKit features** — Cache mounts, secrets, multi-platform builds
6. **Fast startup** — Eager dependencies, lazy application code
## Quick Reference
### Python API Services (FastAPI, Flask)
```dockerfile
# syntax=docker/dockerfile:1.7
FROM python:3.11.11-slim AS base
WORKDIR /app
# Install system dependencies (cached unless changed)
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN groupadd -g 1000 app && \
useradd -m -u 1000 -g app app
# ─── Build stage ───
FROM base AS builder
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Install dependencies with cache mount
COPY pyproject.toml ./
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir .
# ─── Production stage ───
FROM base AS production
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
COPY . .
USER app
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD python -c "import httpx; httpx.get('http://localhost:8000/health', timeout=2)"
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
```
### Multi-Runtime Sandbox (Python + Node + Tools)
```dockerfile
# syntax=docker/dockerfile:1.7
FROM ubuntu:22.04.5 AS base
ENV DEBIAN_FRONTEND=noninteractive \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8
# Single apt layer for all system packages
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
# Core utilities
bash curl wget git jq unzip ca-certificates \
# Build tools (for native extensions)
build-essential libffi-dev libssl-dev \
# FUSE for S3 mount
fuse libfuse2 \
# Process management
tini \
# Python
python3.11 python3.11-venv python3.11-dev python3-pip \
&& ln -sf /usr/bin/python3.11 /usr/bin/python3 \
&& ln -sf /usr/bin/python3.11 /usr/bin/python \
&& rm -rf /var/lib/apt/lists/*
# Python package installs with cache mount
RUN --mount=type=cache,target=/root/.cache/pip \
python3 -m pip install --no-cache-dir --upgrade pip setuptools wheel
# Node.js via official NodeSource script
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y --no-install-recommends nodejs && \
rm -rf /var/lib/apt/lists/* && \
npm install -g npm@latest
# Create non-root user
RUN groupadd -g 1000 agent && \
useradd -m -u 1000 -g agent -s /bin/bash agent
USER agent
WORKDIR /home/agent
ENTRYPOINT ["tini", "--"]
CMD ["/bin/bash"]
```
### Development vs Production Patterns
```dockerfile
# ─── Development stage (hot reload, debug tools) ───
FROM base AS development
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir -e ".[dev]"
COPY . .
# Mount source as volume for hot reload
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--reload"]
# ─── Production stage (minimal, optimized) ───
FROM base AS production
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY . .
USER app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]
```
## Essential Patterns
### Version Pinning
```dockerfile
# ❌ NEVER use latest
FROM python:3.11-slim
# ✅ ALWAYS pin to patch version
FROM python:3.11.11-slim
# ✅ Pin all base images with digest for immutability
FROM python:3.11.11-slim@sha256:abc123...
```
Check latest versions:
- Python: https://hub.docker.com/_/python/tags
- Node: https://hub.docker.com/_/node/tags
- Ubuntu: https://hub.docker.com/_/ubuntu/tags
### BuildKit Cache Mounts
```dockerfile
# ❌ Old way — downloads every build
RUN pip install -r requirements.txt
# ✅ New way — reuses download cache
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# ✅ npm cache mount
RUN --mount=type=cache,target=/root/.npm \
npm ci --prefer-offline
# ✅ apt cache mount (shared across concurrent builds)
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y package-name
```
### Layer Ordering for Optimal Caching
```dockerfile
# Install dependencies (rarely change) — cached ✅
COPY pyproject.toml ./
RUN pip install .
# Copy application code (changes often) — rebuilt on every change ✅
COPY . .
```
### Health Checks
```dockerfile
# Python API
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD python -c "import httpx; httpx.get('http://localhost:8000/health')"
# Node.js API
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
# General process check
HEALTHCHECK --interval=30s --timeout=5s CMD pgrep -x python3 || exit 1
```
### Security Hardening
```dockerfile
# 1. Non-root user
RUN groupadd -g 1000 app && \
useradd -m -u 1000 -g app app
USER app
# 2. Read-only root filesystem (in docker-compose or k8s)
# docker run --read-only --tmpfs /tmp ...
# 3. Drop capabilities (in docker-compose)
# security_opt:
# - no-new-privileges:true
# cap_drop:
# - ALL
# 4. Minimal base image (distroless for Python/Node)
FROM gcr.io/distroless/python3-debian12:latest
```
## docker-compose.yml Best Practices
```yaml
services:
api:
build:
context: .
dockerfile: Dockerfile
target: production # Multi-stage target
cache_from:
- type=registry,ref=ghcr.io/org/api:buildcache
image: org/api:latest
restart: unless-stopped
# Security
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /tmp
# Resources
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
# Health check
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
# Env
env_file: .env
environment:
- NODE_ENV=production
```
## .dockerignore
**CRITICAL**: Always create `.dockerignore` to exclude unnecessary files from build context.
```
# Version control
.git/
.github/
.gitignore
# Python
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
*.so
*.egg-info/
dist/
build/
.venv/
venv/
*.pytest_cache/
.coverage
# Node
node_modules/
npm-debug.log*
.npm/
# IDE
.vscode/
.idea/
*.swp
*.swo
.DS_Store
# Env files (never copy .env to image)
.env
.env.*
!.env.example
# CI/CD
.github/
*.md
!README.md
# Docs
docs/
*.md
```
## Dockerfile Review Checklist
When creating or reviewing a Dockerfile, verify:
### Performance
- [ ] Multi-stage build for services with build dependencies
- [ ] `--mount=type=cache` for pip/npm/apt downloads
- [ ] Layer ordering: system packages → language runtime → dependencies → app code
- [ ] `.dockerignore` excludes unnecessary files
- [ ] Single `apt-get update && install && rm -rf` per stage (not multiple RUN commands)
### Security
- [ ] Base image pinned to specific version (no `:latest`)
- [ ] Non-root user for runtime
- [ ] Minimal base image (slim, alpine, or distroless)
- [ ] No secrets in ENV or build args (use `--mount=type=secret` instead)
- [ ] Health check defined
### Size
- [ ] `--no-install-recommends` on apt-get
- [ ] `rm -rf /var/lib/apt/lists/*` after apt-get
- [ ] `--no-cache-dir` on pip installs
- [ ] Multi-stage excludes build tools from final image
- [ ] Production stage only includes runtime dependencies
### Correctness
- [ ] `WORKDIR` set before COPY
- [ ] Correct user ownership for copied files if using non-root user
- [ ] `EXPOSE` matches actual port
- [ ] `CMD`/`ENTRYPOINT` is production-appropriate (no `--reload`)
- [ ] Environment variables have sensible defaults
## Common Mistakes to Avoid
### ❌ Installing dev dependencies in production
```dockerfile
FROM python:3.11-slim
RUN pip install -e ".[dev]" # Includes pytest, debug tools, etc.
```
### ✅ Separate dev and prod stages
```dockerfile
FROM base AS development
RUN pip install -e ".[dev]"
FROM base AS production
RUN pip install . # Prod deps only
```
### ❌ Running as root
```dockerfile
CMD ["uvicorn", "app:main"] # Runs as root
```
### ✅ Create and use non-root user
```dockerfile
RUN useradd -m app
USER app
CMD ["uvicorn", "app:main"]
```
### ❌ Copying before installing dependencies
```dockerfile
COPY . . # Invalidates cache on every code change
RUN pip install -r requirements.txt
```
### ✅ Install dependencies first
```dockerfile
COPY requirements.txt .
RUN pip install -r requirements.txt # Cached unless requirements.txt changes
COPY . .
```
### ❌ Using `:latest` tags
```dockerfile
FROM python:3-slim # Breaks reproducibility
```
### ✅ Pin to patch version
```dockerfile
FROM python:3.11.11-slim
```
### ❌ Multiple apt-get updates
```dockerfile
RUN apt-get update && apt-get install -y curl
RUN apt-get update && apt-get install -y git # Second update is wasted
```
### ✅ Single apt layer
```dockerfile
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
```
## Building Images
### Enable BuildKit
```bash
export DOCKER_BUILDKIT=1
# Or in docker-compose.yml
export COMPOSE_DOCKER_CLI_BUILD=1
```
### Multi-platform builds
```bash
# For ARM64 Macs building x86_64 images
docker buildx build \
--platform linux/amd64 \
--tag org/app:latest \
--push \
.
# Build for both platforms
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag org/app:latest \
--push \
.
```
### Cache optimization
```bash
# Use inline cache for CI
docker buildx build \
--cache-from type=registry,ref=org/app:buildcache \
--cache-to type=registry,ref=org/app:buildcache,mode=max \
--tag org/app:latest \
--push \
.
```
## Additional Resources
- For detailed explanations and edge cases, see [reference.md](reference.md)
- For complete working examples, see [templates/](templates/)
- For image size comparison and benchmarks, see [optimization.md](optimization.md)
## When NOT to Use This Skill
- Creating `docker-compose.yml` for simple local dev (just use official images)
- Debugging running containers (use `docker logs`, `docker exec` instead)
- Container orchestration at scale (Kubernetes/ECS patterns differ significantly)Related Skills
featbit-deployment-docker
Expert guidance for deploying FeatBit with Docker Compose across three tiers - Standalone (PostgreSQL only), Standard (PostgreSQL/MongoDB + Redis), and Professional (+ ClickHouse + Kafka). Use when user mentions "docker-compose", "deploy with Docker", "standalone vs standard vs pro", works with docker-compose.yml files, or asks about container configuration, environment variables, or production Docker setup.
dockerfile-optimization
Optimize Dockerfiles for smaller images, faster builds, better caching, and security. Use this skill when writing, reviewing, or debugging Dockerfiles.
Docker Hub Automation
Automate Docker Hub tasks via Rube MCP (Composio): repositories, images, tags, and container registry management. Always search tools first for current schemas.
docker
Docker y Compose. Proyecto usa este skill; contenido canónico en .ai-system.
docker-workflow
Comprehensive Docker containerization workflow covering multi-stage builds, docker-compose orchestration, image optimization, debugging, and production best practices. Use when containerizing applications, setting up development environments, or deploying with Docker.
docker-vigil-orchestration
Docker Compose orchestration for Vigil Guard v2.0.0 microservices (11 services). Use when deploying services, managing containers, troubleshooting Docker network issues, working with vigil-net, configuring docker-compose.yml, handling service dependencies, or working with 3-branch detection services (heuristics, semantic, prompt-guard).
docker-to-k8s-manifests
Automatically generate optimized Kubernetes deployment manifests from Dockerfile and docker-compose configurations with proper resource limits and health checks.
docker-test-environments
Docker-based test environment management for isolated, reproducible test execution. Create Docker Compose environments, manage test containers, configure service dependencies, and integrate with CI/CD pipelines.
docker-setup
Dockerfile and Docker Compose patterns with multi-stage builds, layer optimization, security hardening, and health checks. Use when containerizing applications, writing Dockerfiles, or setting up Docker Compose environments.
docker-optimize
Audit and optimize Dockerfiles and docker-compose files for size, security, build speed, and best practices. Triggers on: optimize dockerfile, audit docker, fix dockerfile, docker best practices, docker compose security.
docker-node
Containerization for TypeScript/Node.js applications. Use when deploying Node.js backends, need consistent dev environments, or setting up CI/CD pipelines. Covers multi-stage builds, docker-compose for development, and production optimization. Choose this skill for containerizing tRPC/Express APIs with Prisma.
docker-manage
Manage Docker containers and services efficiently