Docker Patterns Docker and Docker Compose patterns for local development, container security, networking, volume strategies, and multi-service orchestration.
affaan-m 160,286 Sterne 23.02.2026
name
docker-patterns
description
Docker and Docker Compose patterns for local development, container security, networking, volume strategies, and multi-service orchestration.
origin
ECC
Docker Patterns
Docker and Docker Compose best practices for containerized development.
When to Activate
Setting up Docker Compose for local development
Designing multi-container architectures
Troubleshooting container networking or volume issues
Reviewing Dockerfiles for security and size
Migrating from local dev to containerized workflow
Docker Compose for Local Development
Standard Web App Stack
docker-compose.yml
services:
app:
build:
context:
.
target:
dev
Use dev stage of multi-stage Dockerfile
ports:
"3000:3000"
volumes:
.:/app
Bind mount for hot reload
/app/node_modules
Anonymous volume -- preserves container deps
Schnellinstallation
Docker Patterns npx skillvault add affaan-m/affaan-m-everything-claude-code-skills-docker-patterns-skill-md
Sterne 160,286
Aktualisiert 23.02.2026
Beruf
environment:
DATABASE_URL=postgres://postgres:postgres@db:5432/app_dev
REDIS_URL=redis://redis:6379/0
NODE_ENV=development
depends_on:
db:
condition:
service_healthy
redis:
condition:
service_started
command:
npm
run
dev
db:
image:
postgres:16-alpine
ports:
"5432:5432"
environment:
POSTGRES_USER:
postgres
POSTGRES_PASSWORD:
postgres
POSTGRES_DB:
app_dev
volumes:
pgdata:/var/lib/postgresql/data
./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test:
[
"CMD-SHELL"
,
"pg_isready -U postgres"
]
interval:
5s
timeout:
3s
retries:
5
redis:
image:
redis:7-alpine
ports:
"6379:6379"
volumes:
Local email testing
image:
axllent/mailpit
ports:
Web UI
SMTP volumes:
pgdata:
redisdata:
Development vs Production Dockerfile
Stage: dependencies FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:22-alpine AS dev
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
Stage: build FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build && npm prune --production
Stage: production (minimal image) FROM node:22-alpine AS production
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001
USER appuser
COPY --from=build --chown=appuser:appgroup /app/dist ./dist
COPY --from=build --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=build --chown=appuser:appgroup /app/package.json ./
ENV NODE_ENV=production
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]
Override Files
docker-compose.override.yml (auto-loaded, dev-only settings)
services:
app:
environment:
DEBUG=app:*
LOG_LEVEL=debug
ports:
Node.js debugger
docker-compose.prod.yml (explicit for production) services:
app:
build:
target:
production
restart:
always
deploy:
resources:
limits:
cpus:
"1.0"
memory:
512M
Development (auto-loads override)
Production docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Networking
Service Discovery
Services in the same Compose network resolve by service name:
From "app" container:
postgres://postgres:postgres@db:5432/app_dev # "db" resolves to the db container
redis://redis:6379/0 # "redis" resolves to the redis container
Custom Networks
services:
frontend:
networks:
frontend-net
api:
networks:
frontend-net
backend-net
db:
networks:
Only reachable from api, not frontend
networks:
frontend-net:
backend-net:
Exposing Only What's Needed
services:
db:
ports:
Only accessible from host, not network
Omit ports entirely in production -- accessible only within Docker network Volume Strategies
volumes:
Named volume: persists across container restarts, managed by Docker
Bind mount: maps host directory into container (for development)
- ./src:/app/src
Anonymous volume: preserves container-generated content from bind mount override
- /app/node_modules
Common Patterns
services:
app:
volumes:
Source code (bind mount for hot reload)
Protect container's node_modules from host
Protect build cache
db:
volumes: pgdata:/var/lib/postgresql/data
Persistent data ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
Init scripts Container Security
Dockerfile Hardening
FROM node:22.12-alpine3.20
2. Run as non-root RUN addgroup -g 1001 -S app && adduser -S app -u 1001
USER app
3. Drop capabilities (in compose)
4. Read-only root filesystem where possible
5. No secrets in image layers
Compose Security
services:
app:
security_opt:
no
-new-privileges:true
read_only:
true
tmpfs:
/tmp
/app/.cache
cap_drop:
ALL
cap_add:
Only if binding to ports < 1024
GOOD: Use environment variables (injected at runtime)
services:
app:
env_file:
Never commit .env to git
environment:
Inherits from host environment
GOOD: Docker secrets (Swarm mode)
secrets:
db_password:
file:
./secrets/db_password.txt
services:
db:
secrets:
BAD: Hardcoded in image
ENV API_KEY=sk-proj-xxxxx # NEVER DO THIS .dockerignore
node_modules
.git
.env
.env.*
dist
coverage
.log
.next
.cache
docker-compose .yml
Dockerfile*
README.md
tests/
Debugging
Common Commands
View logs docker compose logs -f app
Follow app logs docker compose logs --
tail
=50 db
Last 50 lines from db
Execute commands in running container docker compose
exec
app sh
Shell into app docker compose
exec
db psql -U postgres
Connect to postgres
Inspect
Running services
Processes in each container
Resource usage
Rebuild docker compose up --build
Rebuild images docker compose build --no-cache app
Force full rebuild
Clean up
Stop and remove containers
Also remove volumes (DESTRUCTIVE)
Remove unused images/containers
Check DNS resolution inside container docker compose
exec
app nslookup db
Check connectivity
Inspect network docker network
ls
docker network inspect <project>_default
Anti-Patterns
BAD: Using docker compose in production without orchestration
Use Kubernetes, ECS, or Docker Swarm for production multi-container workloads
BAD: Storing data in containers without volumes
Containers are ephemeral -- all data lost on restart without volumes
BAD: Running as root
Always create and use a non-root user
BAD: Using :latest tag
Pin to specific versions for reproducible builds
BAD: One giant container with all services
Separate concerns: one process per container
BAD: Putting secrets in docker-compose.yml
Use .env files (gitignored) or Docker secrets 02
Use dev stage of multi-stage Dockerfile
Docker Patterns | Skills Pool