# 🐳 Docker Compose Guide *Comprehensive guide for Docker Compose usage in the homelab environment* ## 📋 Overview This guide covers Docker Compose best practices, patterns, and configurations used throughout the homelab infrastructure for consistent and maintainable container deployments. ## 🏗️ Standard Compose Structure ### Basic Template ```yaml version: '3.8' services: service-name: image: organization/image:latest container_name: service-name restart: unless-stopped environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles volumes: - ./config:/config - /data/service:/data ports: - "8080:8080" networks: - homelab labels: - "traefik.enable=true" - "traefik.http.routers.service.rule=Host(`service.vish.gg`)" - "com.centurylinklabs.watchtower.enable=true" networks: homelab: external: true ``` ## 🔧 Configuration Patterns ### Environment Variables ```yaml environment: # User/Group IDs (required for file permissions) - PUID=1000 - PGID=1000 # Timezone (consistent across all services) - TZ=America/Los_Angeles # Service-specific configuration - DATABASE_URL=postgresql://user:REDACTED_PASSWORD@db:5432/dbname - REDIS_URL=redis://redis:6379 # Security settings - SECURE_SSL_REDIRECT=true - SESSION_COOKIE_SECURE=true ``` ### Volume Mapping ```yaml volumes: # Configuration (relative to compose file) - ./config:/config - ./data:/data # Shared storage (absolute paths) - /mnt/storage/media:/media:ro - /mnt/storage/downloads:/downloads # System integration - /var/run/docker.sock:/var/run/docker.sock:ro - /etc/localtime:/etc/localtime:ro ``` ### Network Configuration ```yaml networks: # External network (created separately) homelab: external: true # Internal network (service-specific) internal: driver: bridge internal: true ``` ## 🏷️ Labeling Standards ### Traefik Integration ```yaml labels: # Enable Traefik - "traefik.enable=true" # HTTP Router - "traefik.http.routers.service.rule=Host(`service.vish.gg`)" - "traefik.http.routers.service.entrypoints=websecure" - "traefik.http.routers.service.tls.certresolver=letsencrypt" # Service configuration - "traefik.http.services.service.loadbalancer.server.port=8080" # Middleware - "traefik.http.routers.service.middlewares=auth@file" ``` ### Watchtower Configuration ```yaml labels: # Enable automatic updates - "com.centurylinklabs.watchtower.enable=true" # Update schedule (optional) - "com.centurylinklabs.watchtower.schedule=0 0 4 * * *" # Notification settings - "com.centurylinklabs.watchtower.notification-url=ntfy://ntfy.vish.gg/watchtower" ``` ### Monitoring Labels ```yaml labels: # Prometheus monitoring - "prometheus.io/scrape=true" - "prometheus.io/port=9090" - "prometheus.io/path=/metrics" # Service metadata - "homelab.service.category=media" - "homelab.service.tier=production" - "homelab.service.owner=vish" ``` ## 🔐 Security Best Practices ### User and Permissions ```yaml # Always specify user/group IDs environment: - PUID=1000 - PGID=1000 # Or use user directive user: "1000:1000" # For root-required services, minimize privileges security_opt: - no-new-privileges:true ``` ### Secrets Management ```yaml # Use Docker secrets secrets: db_password: "REDACTED_PASSWORD" ./secrets/db_password.txt services: app: secrets: - db_password environment: - DB_PASSWORD_FILE=/run/secrets/db_password ``` ### Network Security ```yaml # Avoid host networking network_mode: host # ❌ Avoid this # Use custom networks instead networks: - internal # ✅ Preferred approach # Limit exposed ports ports: - "127.0.0.1:8080:8080" # ✅ Bind to localhost only ``` ## 📊 Resource Management ### Resource Limits ```yaml services: service-name: deploy: resources: limits: cpus: '2.0' memory: 2G reservations: cpus: '0.5' memory: 512M ``` ### Health Checks ```yaml services: service-name: healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s ``` ### Restart Policies ```yaml # Standard restart policy restart: unless-stopped # Alternative policies restart: "no" # Never restart restart: always # Always restart restart: on-failure # Restart on failure only ``` ## 🗂️ Multi-Service Patterns ### Database Integration ```yaml version: '3.8' services: app: image: myapp:latest depends_on: - database environment: - DATABASE_URL=postgresql://user:REDACTED_PASSWORD@database:5432/myapp networks: - internal database: image: postgres:15 environment: - POSTGRES_DB=myapp - POSTGRES_USER=user - POSTGRES_PASSWORD_FILE=/run/secrets/db_password volumes: - db_data:/var/lib/postgresql/data networks: - internal secrets: - db_password volumes: db_data: networks: internal: driver: bridge secrets: db_password: "REDACTED_PASSWORD" ./secrets/db_password.txt ``` ### Reverse Proxy Integration ```yaml services: app: image: myapp:latest networks: - homelab labels: - "traefik.enable=true" - "traefik.http.routers.app.rule=Host(`app.vish.gg`)" - "traefik.http.routers.app.entrypoints=websecure" - "traefik.http.routers.app.tls.certresolver=letsencrypt" networks: homelab: external: true ``` ## 🔄 Development vs Production ### Development Override ```yaml # docker-compose.override.yml version: '3.8' services: app: build: . volumes: - .:/app environment: - DEBUG=true ports: - "8080:8080" ``` ### Production Configuration ```yaml # docker-compose.prod.yml version: '3.8' services: app: image: myapp:v1.2.3 restart: unless-stopped deploy: resources: limits: memory: 1G logging: driver: "json-file" options: max-size: "10m" max-file: "3" ``` ## 📝 Documentation Standards ### Service Documentation ```yaml # At the top of each compose file # Service: Application Name # Purpose: Brief description of what this service does # Access: How to access the service (URL, port, etc.) # Dependencies: Other services this depends on # Volumes: Important volume mappings # Configuration: Key environment variables ``` ### Inline Comments ```yaml services: app: image: myapp:latest container_name: myapp restart: unless-stopped environment: # Required: User/group for file permissions - PUID=1000 - PGID=1000 # Optional: Custom configuration - CUSTOM_SETTING=value volumes: # Configuration directory - ./config:/config # Data storage (persistent) - app_data:/data ports: # Web interface - "8080:8080" ``` ## 🚀 Deployment Strategies ### GitOps Deployment ```yaml # Compose files are deployed via Portainer GitOps # Repository: https://git.vish.gg/Vish/homelab.git # Branch: main # Automatic deployment on git push ``` ### Manual Deployment ```bash # Deploy stack docker-compose up -d # Update stack docker-compose pull docker-compose up -d # Remove stack docker-compose down ``` ### Stack Management ```bash # View running services docker-compose ps # View logs docker-compose logs -f service-name # Execute commands docker-compose exec service-name bash # Scale services docker-compose up -d --scale worker=3 ``` ## 🔍 Troubleshooting ### Common Issues ```bash # Check service status docker-compose ps # View logs docker-compose logs service-name # Validate configuration docker-compose config # Check resource usage docker stats ``` ### Debug Commands ```bash # Inspect container docker inspect container-name # Check networks docker network ls docker network inspect network-name # Volume inspection docker volume ls docker volume inspect volume-name ``` ## 📊 Monitoring Integration ### Prometheus Metrics ```yaml services: app: labels: - "prometheus.io/scrape=true" - "prometheus.io/port=9090" - "prometheus.io/path=/metrics" ``` ### Log Management ```yaml services: app: logging: driver: "json-file" options: max-size: "10m" max-file: "3" labels: "service,environment" ``` ## 🔧 Advanced Patterns ### Init Containers ```yaml services: app: image: myapp:latest depends_on: init: condition: service_completed_successfully init: image: busybox command: ["sh", "-c", "echo 'Initialization complete'"] ``` ### Sidecar Containers ```yaml services: app: image: myapp:latest volumes: - shared_data:/data sidecar: image: nginx:alpine volumes: - shared_data:/usr/share/nginx/html:ro ports: - "80:80" volumes: shared_data: ``` ## 📚 Additional Resources ### External Documentation - [Docker Compose Reference](https://docs.docker.com/compose/compose-file/) - [Docker Best Practices](https://docs.docker.com/develop/best-practices/) - [Traefik Docker Integration](https://doc.traefik.io/traefik/providers/docker/) ### Internal Resources - [Development Guide](DEVELOPMENT.md) - [GitOps Deployment Guide](../admin/gitops-deployment-guide.md) - [Security Guidelines](../security/SECURITY_GUIDELINES.md) --- **Last Updated**: February 24, 2026 **Docker Compose Version**: 3.8+ recommended **Status**: ✅ **PRODUCTION** - Used across all homelab services