with one click
docker-patterns
// Provides best practices for containerization, multi-stage builds, container orchestration, and Docker security hardening.
// Provides best practices for containerization, multi-stage builds, container orchestration, and Docker security hardening.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | docker-patterns |
| description | Provides best practices for containerization, multi-stage builds, container orchestration, and Docker security hardening. |
Best practices for containerization, multi-stage builds, and container orchestration.
node:20-alpine vs node:20).dockerignore to exclude unnecessary filesImpact: Reduces image size from ~1GB to ~180MB for Node.js apps.
package.json) before source codeRUN commands to reduce layersPattern: Copy package.json ā Install deps ā Copy source ā Build
USER directive)HEALTHCHECK directive)dumb-init)latest)# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Runtime (minimal)
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
See: references/multi-stage-builds.md for complete examples
Always create and switch to a non-root user:
RUN addgroup --system --gid 1001 appgroup && \
adduser --system --uid 1001 appuser
USER appuser
Use dumb-init for proper signal forwarding:
RUN apk add --no-cache dumb-init
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "index.js"]
# docker-compose.yml
services:
app:
read_only: true
tmpfs:
- /tmp
# Scan before deployment
docker scout cves myapp:latest
trivy image --severity HIGH,CRITICAL myapp:latest
See: references/security.md for complete hardening guide
depends_on with condition: service_healthy for startup orderingdocker-compose.override.yml) for local developmentSee: references/docker-compose.md for complete configurations
# ā Bad: Invalidates cache on any file change
COPY . .
RUN npm install
# ā
Good: Cache deps unless package.json changes
COPY package*.json ./
RUN npm ci
COPY . .
| Base Image | Size |
|---|---|
node:20 | ~1GB |
node:20-slim | ~250MB |
node:20-alpine | ~180MB |
distroless/nodejs20 | ~130MB |
# Build with cache
docker build -t myapp:latest .
# Build without cache
docker build --no-cache -t myapp:latest .
# Build specific stage
docker build --target builder -t myapp:builder .
# Run with docker compose
docker compose up -d
# View logs
docker compose logs -f app
# Clean up
docker system prune -a
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
services:
app:
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Expose /health endpoint that checks:
See: references/dockerfile-examples.md for implementation
Essential files to exclude:
# Dependencies
node_modules
# Build outputs
dist
build
.next
# Development files
.git
*.md
Dockerfile*
# Secrets
.env*
!.env.example
# Tests
tests
coverage
# Shell into running container
docker exec -it container_name sh
# View logs
docker logs -f container_name
# Inspect container
docker inspect container_name
# Check resource usage
docker stats container_name
# Run health check manually
docker exec container_name wget -O- http://localhost:3000/health
See: references/debugging.md for complete troubleshooting guide
latest Tagā Bad: Unpredictable builds, hard to rollback
FROM node:latest
ā Good: Pin specific versions
FROM node:20.11.0-alpine3.19
ā Bad: Security risk
FROM node:20-alpine
CMD ["node", "index.js"]
ā Good: Create non-root user
FROM node:20-alpine
RUN adduser -D appuser
USER appuser
CMD ["node", "index.js"]
ā Bad: Secrets in image layers
ENV API_KEY=sk-abc123
ā Good: Use environment variables or Docker secrets
services:
app:
env_file: .env
ā Bad: No health monitoring
CMD ["node", "index.js"]
ā Good: Add health check
HEALTHCHECK CMD wget --spider http://localhost:3000/health || exit 1
CMD ["node", "index.js"]
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/OWNER/REPO:COMMIT_SHA # Use GitHub Actions syntax: ghcr.io/${{github.repository}}:${{github.sha}}
cache-from: type=gha
cache-to: type=gha,mode=max
# Cache npm packages across builds
RUN --mount=type=cache,target=/root/.npm \
npm ci --only=production
references/dockerfile-examples.md - Complete examples for Node.js, Python, Goreferences/multi-stage-builds.md - Detailed multi-stage patterns and optimizationreferences/docker-compose.md - Development and production configurationsreferences/security.md - Complete security hardening guidereferences/debugging.md - Troubleshooting commands and techniques