Docker best practices
Skill timdevai/proteus/skills/community/from-rohitg00/docker-best-practices
Docker best practices including multi-stage builds, compose patterns, image optimization, and securityFrom its SKILL.md
npx -y skills add timdevai/proteus --skill docker-best-practicesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 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.
SKILL.md
3.7 KB, 984 tokens by cl100k_base, as published. Nobody here has run it
Docker Best Practices
Multi-Stage Build
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
FROM node:22-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine AS runtime
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001 -G appgroup
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/healthz || exit 1
CMD ["node", "dist/server.js"]
Separate dependency installation from build steps. Final stage contains only runtime artifacts.
Python Multi-Stage
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
FROM python:3.12-slim
WORKDIR /app
RUN useradd --create-home appuser
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY . .
USER appuser
CMD ["gunicorn", "app:create_app()", "-b", "0.0.0.0:8000", "-w", "4"]
Docker Compose
services:
api:
build:
context: .
dockerfile: Dockerfile
target: runtime
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/app
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: app
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d app"]
interval: 5s
timeout: 3s
retries: 5
cache:
image: redis:7-alpine
command: redis-server --maxmemory 128mb --maxmemory-policy allkeys-lru
volumes:
pgdata:
.dockerignore
node_modules
.git
.env*
*.md
docker-compose*.yml
.github
coverage
dist
Always include a .dockerignore to reduce build context size and prevent leaking secrets.
Image Optimization Tips
# Check image size breakdown
docker history --human --no-trunc <image>
# Use dive for layer analysis
dive <image>
# Multi-arch build
docker buildx build --platform linux/amd64,linux/arm64 -t registry/app:1.0 --push .
Combine RUN commands to reduce layers. Order instructions from least to most frequently changing for cache efficiency.
Anti-Patterns
- Running as root inside containers
- Using
ADDwhenCOPYsuffices (ADD auto-extracts tarballs, pulls URLs) - Storing secrets in environment variables in Dockerfiles
- Not pinning base image versions (
FROM node:latest) - Missing
.dockerignorecausing large build contexts - Installing dev dependencies in production images
Checklist
- Multi-stage build separates build and runtime stages
- Non-root user created and used with
USERdirective - Base images pinned to specific versions (e.g.,
node:22-alpine) -
.dockerignoreexcludes.git,node_modules,.env -
HEALTHCHECKinstruction defined - Production image contains no build tools or dev dependencies
-
docker-composeusesdepends_onwith health conditions - Secrets passed via build secrets or runtime mounts, not
ENVin Dockerfile
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.