Files
open-claw-team/.openclaw/workspace/skills/docker-patterns/SKILL.md
T

185 lines
3.9 KiB
Markdown

---
name: docker-patterns
description: Docker and Docker Compose best practices — multi-stage builds, networking, volumes, container security, optimization. Use when writing Dockerfiles, docker-compose.yml, or containerizing applications.
---
# Docker Patterns
Based on ECC docker-patterns skill.
## Dockerfile Best Practices
### Pin base image versions
```dockerfile
# Good
FROM node:20.11.0-alpine3.19
# Bad — version changes can break builds
FROM node:latest
```
### Multi-Stage Builds for minimal images
```dockerfile
# Stage 1: Build
FROM golang:1.22-bookworm AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o myapp -ldflags="-s -w"
# Stage 2: Runtime (small image)
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/myapp /myapp
USER 1000
CMD ["/myapp"]
```
### Layer caching optimization
```dockerfile
# Copy dependency files first, install, then copy rest
COPY package.json package-lock.json ./
RUN npm ci --production=false
COPY . .
```
### .dockerignore
```
node_modules/
.git/
.env
dist/
*.log
__pycache__
*.pyc
```
## Docker Compose Patterns
### Production-ready compose
```yaml
name: myapp
services:
app:
image: myapp:${APP_VERSION:-latest}
restart: unless-stopped
environment:
DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@db:5432/myapp
NODE_ENV: production
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000/healthz"]
interval: 30s
timeout: 10s
retries: 3
networks: [app-net]
deploy:
resources:
limits:
memory: 512M
cpus: "0.5"
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 10s
timeout: 5s
retries: 5
networks:
app-net:
driver: bridge
volumes:
pgdata:
```
## Container Security
### Run as non-root
```dockerfile
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
```
### No sensitive data in images
- Never COPY .env files
- Never hardcode credentials in Dockerfile
- Use docker secrets, env vars at runtime
### Minimize attack surface
- Use Alpine or distroless base images
- Remove build tools from final image (multi-stage)
- Only expose needed ports
### Scan images
```bash
# Scan for vulnerabilities
docker scout cve myapp:latest
# Scan Dockerfile for issues
hadolint Dockerfile
```
## Networking
### Service-to-service communication
```yaml
# Compose: services can reach each other by name
# app can reach db at hostname "db" on port 5432
```
### Isolating networks
```yaml
networks:
frontend: # Public-facing services
backend: # DB, cache (not exposed to outside)
```
## Volumes
### Named volumes (data persistence)
```yaml
volumes:
- pgdata:/var/lib/postgresql/data # Persisted data
- redis-data:/data
```
### Bind mounts (development)
```yaml
volumes:
- ./src:/app/src:ro # Read-only code mount
- /data:/app/logs # Log output
```
## Optimization Tips
1. **Smallest base image**: `scratch` > `alpine` > `slim` > `full`
2. **Layer count**: Fewer layers = smaller image
3. **COPY order**: Dependencies first, then application code
4. **Combined RUN commands**: `RUN apt-get update && apt-get install -y x && rm -rf /var/lib/apt/lists/*`
5. **Multi-stage**: Build tools in builder, runtime only in final
6. **Distroless for Go/Rust**: `FROM scratch` with just the binary
## Checklist
- [ ] Base image pinned to specific version
- [ ] Multi-stage build for production
- [ ] Non-root user
- [ ] .dockerignore complete
- [ ] Health checks configured
- [ ] No secrets in image
- [ ] Minimal base image
- [ ] Volumes for persistent data
- [ ] Network isolation