Files
APAW/.kilo/skills/docker-compose/patterns/basic-service.md
¨NW¨ 68daaf11a6 feat: add Docker/DevOps skills and devops-engineer agent
- Add devops-engineer agent (Docker, Kubernetes, CI/CD)
- Add docker-compose skill with basic-service pattern
- Add docker-swarm skill with HA web app example
- Add docker-security skill (OWASP, secrets, hardening)
- Add docker-monitoring skill (Prometheus, Grafana, logs)
- Add docker.md rules
- Update orchestrator with devops-engineer permission
- Update security-auditor with Docker security checklist
- Update backend-developer, frontend-developer, go-developer with task permissions

All models verified: deepseek-v3.2, nemotron-3-super (available in KILO_SPEC)
2026-04-05 15:05:58 +01:00

8.6 KiB

Docker Compose Patterns

Pattern: Multi-Service Application

Complete pattern for a typical web application with API, database, cache, and reverse proxy.

version: '3.8'

services:
  # Reverse Proxy
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - api
    networks:
      - frontend
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M
    healthcheck:
      test: ["CMD", "nginx", "-t"]
      interval: 30s
      timeout: 10s
      retries: 3

  # API Service
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://db:5432/app
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    networks:
      - frontend
      - backend
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  # Database
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: ${DB_USER:-app}
      POSTGRES_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD required}
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./init-scripts:/docker-entrypoint-initdb.d:ro
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G

  # Cache
  cache:
    image: redis:7-alpine
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis-data:/data
    networks:
      - backend
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # No external access

volumes:
  postgres-data:
    driver: local
  redis-data:
    driver: local

Pattern: Development Override

Development-specific configuration with hot reload and debugging.

# docker-compose.dev.yml
version: '3.8'

services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile.dev
    volumes:
      - ./api/src:/app/src:ro
      - ./api/tests:/app/tests:ro
      - /app/node_modules
    environment:
      - NODE_ENV=development
      - DEBUG=app:*
    ports:
      - "3000:3000"
      - "9229:9229"  # Node.js debugger
    command: npm run dev

  db:
    ports:
      - "5432:5432"  # Expose for local tools

  cache:
    ports:
      - "6379:6379"  # Expose for local tools
# Usage
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up

Pattern: Production Override

Production-optimized configuration with security and performance settings.

# docker-compose.prod.yml
version: '3.8'

services:
  api:
    image: myapp/api:${VERSION}
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
      rollback_config:
        parallelism: 1
        delay: 10s
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
    environment:
      - NODE_ENV=production
    secrets:
      - db_password
      - jwt_secret
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

secrets:
  db_password:
    external: true
  jwt_secret:
    external: true
# Usage
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Pattern: Health Check Dependency

Waiting for dependent services to be healthy before starting.

services:
  app:
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER"]
      interval: 10s
      timeout: 5s
      retries: 5

  cache:
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

Pattern: Secrets Management

Using Docker secrets for sensitive data (Swarm mode).

services:
  app:
    secrets:
      - db_password
      - api_key
      - jwt_secret
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password
      - API_KEY_FILE=/run/secrets/api_key
      - JWT_SECRET_FILE=/run/secrets/jwt_secret

secrets:
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    file: ./secrets/api_key.txt
  jwt_secret:
    external: true  # Created via: echo "secret" | docker secret create jwt_secret -

Pattern: Resource Limits

Setting resource constraints for containers.

services:
  api:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
    # Alternative for non-Swarm
    mem_limit: 1G
    memswap_limit: 1G
    cpus: 1

Pattern: Network Isolation

Segmenting networks for security.

services:
  web:
    networks:
      - frontend
      - backend

  api:
    networks:
      - backend
      - database

  db:
    networks:
      - database

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
  database:
    driver: bridge
    internal: true  # No internet access

Pattern: Volume Management

Different volume types for different use cases.

services:
  app:
    volumes:
      # Named volume (managed by Docker)
      - app-data:/app/data
      # Bind mount (host directory)
      - ./config:/app/config:ro
      # Anonymous volume (for node_modules)
      - /app/node_modules
      # tmpfs (temporary in-memory)
      - type: tmpfs
        target: /tmp
        tmpfs:
          size: 100M

volumes:
  app-data:
    driver: local
    labels:
      - "app=myapp"
      - "type=persistent"

Pattern: Logging Configuration

Configuring logging drivers and options.

services:
  app:
    logging:
      driver: "json-file"  # Default
      options:
        max-size: "10m"
        max-file: "3"
        labels: "app,environment"
        tag: "{{.ImageName}}/{{.Name}}"

  # Syslog logging
  app-syslog:
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://logserver:514"
        syslog-facility: "daemon"
        tag: "myapp"

  # Fluentd logging
  app-fluentd:
    logging:
      driver: "fluentd"
      options:
        fluentd-address: "localhost:24224"
        tag: "myapp.api"

Pattern: Multi-Environment

Managing multiple environments with overrides.

# Directory structure
# docker-compose.yml          # Base configuration
# docker-compose.dev.yml      # Development overrides
# docker-compose.staging.yml   # Staging overrides
# docker-compose.prod.yml      # Production overrides
# .env                         # Environment variables
# .env.dev                     # Development variables
# .env.staging                 # Staging variables
# .env.prod                    # Production variables

# Development
docker-compose --env-file .env.dev \
  -f docker-compose.yml -f docker-compose.dev.yml up

# Staging
docker-compose --env-file .env.staging \
  -f docker-compose.yml -f docker-compose.staging.yml up -d

# Production
docker-compose --env-file .env.prod \
  -f docker-compose.yml -f docker-compose.prod.yml up -d

Pattern: CI/CD Testing

Running tests in isolated containers.

# docker-compose.test.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=test
      - DATABASE_URL=postgres://test:test@db:5432/test
    depends_on:
      - db
    command: npm test
    networks:
      - test-network

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: test
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
    networks:
      - test-network

networks:
  test-network:
    driver: bridge
# CI pipeline
docker-compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from app
docker-compose -f docker-compose.test.yml down -v