正在加载,请稍候…

Docker Compose for Production: Multi-Service Apps, Secrets, and Health Checks

Use Docker Compose in production — multi-service architectures, Compose Watch, secrets management, health checks, resource limits, and deploying to Docker Swarm.

Docker Compose Beyond Development

Docker Compose has evolved into a production-ready tool with Compose Watch, deploy configs, and built-in secrets.

Production Compose File

# compose.yml
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
    image: myapp/api:latest
    restart: unless-stopped
    environment:
      NODE_ENV: production
      DATABASE_URL: postgresql://db:5432/myapp
    secrets:
      - jwt_secret
      - db_password
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - backend

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: myapp
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U myapp"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 1G
    networks:
      - backend

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
    networks:
      - backend

  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
    depends_on:
      - api
    networks:
      - backend
      - frontend

secrets:
  jwt_secret:
    file: ./secrets/jwt_secret.txt  # Or use Docker Swarm secrets
  db_password:
    file: ./secrets/db_password.txt

volumes:
  postgres_data:
  redis_data:

networks:
  backend:
    driver: bridge
  frontend:
    driver: bridge

Multi-Stage Dockerfile

# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# Development stage  
FROM builder AS development
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]

# Production stage
FROM node:20-alpine AS production
WORKDIR /app
RUN addgroup --system app && adduser --system --group app
COPY --from=builder /app/node_modules ./node_modules
COPY --chown=app:app . .
USER app
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s CMD curl -f http://localhost:3000/health
CMD ["node", "dist/server.js"]

Compose Watch (Hot Reload in Dev)

services:
  api:
    build: .
    develop:
      watch:
        - path: ./src
          action: sync            # Sync files without rebuilding
          target: /app/src
        - path: ./package.json
          action: rebuild         # Full rebuild on package changes
        - path: ./Dockerfile
          action: rebuild
docker compose watch

Deploy to Docker Swarm

docker swarm init

# Create secrets
echo "my-jwt-secret" | docker secret create jwt_secret -
echo "my-db-password" | docker secret create db_password -

# Deploy stack
docker stack deploy -c compose.yml myapp

# Scale service
docker service scale myapp_api=5

# Rolling update
docker service update --image myapp/api:v2 myapp_api

# View logs
docker service logs myapp_api --follow

Resource Monitoring

# View resource usage
docker stats $(docker compose ps -q)

# Prune unused resources
docker system prune -a --volumes