Awesome-claude-code-toolkit docker-best-practices

Docker best practices including multi-stage builds, compose patterns, image optimization, and security

install
source · Clone the upstream repo
git clone https://github.com/rohitg00/awesome-claude-code-toolkit
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/rohitg00/awesome-claude-code-toolkit "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/docker-best-practices" ~/.claude/skills/rohitg00-awesome-claude-code-toolkit-docker-best-practices && rm -rf "$T"
manifest: skills/docker-best-practices/SKILL.md
safety · automated scan (medium risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
  • pip install
  • downloads files (wget)
  • references .env files
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content

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
    ADD
    when
    COPY
    suffices (ADD auto-extracts tarballs, pulls URLs)
  • Storing secrets in environment variables in Dockerfiles
  • Not pinning base image versions (
    FROM node:latest
    )
  • Missing
    .dockerignore
    causing 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
    USER
    directive
  • Base images pinned to specific versions (e.g.,
    node:22-alpine
    )
  • .dockerignore
    excludes
    .git
    ,
    node_modules
    ,
    .env
  • HEALTHCHECK
    instruction defined
  • Production image contains no build tools or dev dependencies
  • docker-compose
    uses
    depends_on
    with health conditions
  • Secrets passed via build secrets or runtime mounts, not
    ENV
    in Dockerfile