# 🚀 Service Deployment Guide **🟡 Intermediate Guide** This guide covers how to deploy new services in the homelab infrastructure, following established patterns and best practices used across all 176 Docker Compose configurations. ## 🎯 Deployment Philosophy ### 🏗️ **Infrastructure as Code** - All services are defined in Docker Compose files - Configuration is version-controlled in Git - Ansible automates deployment and management - Consistent patterns across all services ### 🔄 **Deployment Workflow** ``` Development → Testing → Staging → Production ↓ ↓ ↓ ↓ Local PC → Test VM → Staging → Live Host ``` --- ## 📋 Pre-Deployment Checklist ### ✅ **Before You Start** - [ ] Identify the appropriate host for your service - [ ] Check resource requirements (CPU, RAM, storage) - [ ] Verify network port availability - [ ] Review security implications - [ ] Plan data persistence strategy - [ ] Consider backup requirements ### 🎯 **Host Selection Criteria** | Host Type | Best For | Avoid For | |-----------|----------|-----------| | **Synology NAS** | Always-on services, media, storage | CPU-intensive tasks | | **Proxmox VMs** | Isolated workloads, testing | Resource-constrained apps | | **Physical Hosts** | AI/ML, gaming, high-performance | Simple utilities | | **Edge Devices** | IoT, networking, lightweight apps | Heavy databases | --- ## 🐳 Docker Compose Patterns ### 📝 **Standard Template** Every service follows this basic structure: ```yaml version: '3.9' services: service-name: image: official/image:latest container_name: Service-Name hostname: service-hostname # Security hardening security_opt: - no-new-privileges:true user: 1026:100 # Synology user mapping (adjust per host) read_only: true # For stateless services # Health monitoring healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s # Restart policy restart: on-failure:5 # Resource limits deploy: resources: limits: memory: 512M cpus: '0.5' reservations: memory: 256M # Networking networks: - service-network ports: - "8080:80" # Data persistence volumes: - /volume1/docker/service:/data:rw - /etc/localtime:/etc/localtime:ro # Configuration environment: - TZ=America/Los_Angeles - PUID=1026 - PGID=100 env_file: - .env # Dependencies depends_on: database: condition: service_healthy # Supporting services (database, cache, etc.) database: image: postgres:15 container_name: Service-DB # ... similar configuration networks: service-network: name: service-network ipam: config: - subnet: 192.168.x.0/24 volumes: service-data: driver: local ``` ### 🔧 **Host-Specific Adaptations** #### **Synology NAS** (Atlantis, Calypso, Setillo) ```yaml # User mapping for Synology user: 1026:100 # Volume paths volumes: - /volume1/docker/service:/data:rw - /volume1/media:/media:ro # Memory limits (conservative) deploy: resources: limits: memory: 1G ``` #### **Proxmox VMs** (Homelab, Chicago, Bulgaria) ```yaml # Standard Linux user user: 1000:1000 # Volume paths volumes: - ./data:/data:rw - /etc/localtime:/etc/localtime:ro # More generous resources deploy: resources: limits: memory: 4G cpus: '2.0' ``` #### **Physical Hosts** (Anubis, Guava) ```yaml # GPU access (if needed) runtime: nvidia environment: - NVIDIA_VISIBLE_DEVICES=all # High-performance settings deploy: resources: limits: memory: 16G cpus: '8.0' ``` --- ## 📁 Directory Structure ### 🗂️ **Standard Layout** ``` /workspace/homelab/ ├── HostName/ │ ├── service-name/ │ │ ├── docker-compose.yml │ │ ├── .env │ │ ├── config/ │ │ └── README.md │ └── service-name.yml # Simple services ├── docs/ └── ansible/ ``` ### 📝 **File Naming Conventions** - **Simple services**: `service-name.yml` - **Complex services**: `service-name/docker-compose.yml` - **Environment files**: `.env` or `stack.env` - **Configuration**: `config/` directory --- ## 🔐 Security Best Practices ### 🛡️ **Container Security** ```yaml # Security hardening security_opt: - no-new-privileges:true - apparmor:docker-default - seccomp:unconfined # Only if needed # User namespaces user: 1026:100 # Non-root user # Read-only filesystem read_only: true tmpfs: - /tmp - /var/tmp # Capability dropping cap_drop: - ALL cap_add: - CHOWN # Only add what's needed ``` ### 🔑 **Secrets Management** ```yaml # Use Docker secrets for sensitive data 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 # Custom networks for isolation networks: frontend: internal: false # Internet access backend: internal: true # No internet access services: web: networks: - frontend - backend database: networks: - backend # Database isolated from internet ``` --- ## 📊 Monitoring Integration ### 📈 **Health Checks** ```yaml healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s ``` ### 🏷️ **Prometheus Labels** ```yaml labels: - "prometheus.io/scrape=true" - "prometheus.io/port=8080" - "prometheus.io/path=/metrics" - "service.category=media" - "service.tier=production" ``` ### 📊 **Logging Configuration** ```yaml logging: driver: "json-file" options: max-size: "10m" max-file: "3" labels: "service,environment" ``` --- ## 🚀 Deployment Process ### 1️⃣ **Local Development** ```bash # Create service directory mkdir -p ~/homelab-dev/new-service cd ~/homelab-dev/new-service # Create docker-compose.yml cat > docker-compose.yml << 'EOF' # Your service configuration EOF # Test locally docker-compose up -d docker-compose logs -f ``` ### 2️⃣ **Testing & Validation** ```bash # Health check curl -f http://localhost:8080/health # Resource usage docker stats # Security scan docker scout cves # Cleanup docker-compose down -v ``` ### 3️⃣ **Repository Integration** ```bash # Add to homelab repository cp -r ~/homelab-dev/new-service /workspace/homelab/TargetHost/ # Update documentation echo "## New Service" >> /workspace/homelab/TargetHost/README.md # Commit changes git add . git commit -m "Add new-service to TargetHost" ``` ### 4️⃣ **Ansible Deployment** ```bash # Deploy using Ansible cd /workspace/homelab/ansible ansible-playbook -i inventory.ini deploy-service.yml \ --extra-vars "target_host=atlantis service_name=new-service" # Verify deployment ansible atlantis -i inventory.ini -m shell \ -a "docker ps | grep new-service" ``` --- ## 🔧 Service-Specific Patterns ### 🎬 **Media Services** ```yaml # Common media service pattern services: media-service: image: linuxserver/service:latest environment: - PUID=1026 - PGID=100 - TZ=America/Los_Angeles volumes: - /volume1/docker/service:/config - /volume1/media:/media:ro - /volume1/downloads:/downloads:rw ports: - "8080:8080" ``` ### 🗄️ **Database Services** ```yaml # Database with backup integration services: database: image: postgres:15 environment: - POSTGRES_DB=appdb - POSTGRES_USER=appuser - POSTGRES_PASSWORD_FILE=/run/secrets/db_password volumes: - db_data:/var/lib/postgresql/data - ./backups:/backups secrets: - db_password healthcheck: test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"] ``` ### 🌐 **Web Services** ```yaml # Web service with reverse proxy services: web-app: image: nginx:alpine labels: - "traefik.enable=true" - "traefik.http.routers.webapp.rule=Host(`app.example.com`)" - "traefik.http.services.webapp.loadbalancer.server.port=80" volumes: - ./html:/usr/share/nginx/html:ro ``` --- ## 📋 Deployment Checklist ### ✅ **Pre-Deployment** - [ ] Service configuration reviewed - [ ] Resource requirements calculated - [ ] Security settings applied - [ ] Health checks configured - [ ] Backup strategy planned - [ ] Monitoring integration added ### ✅ **During Deployment** - [ ] Service starts successfully - [ ] Health checks pass - [ ] Logs show no errors - [ ] Network connectivity verified - [ ] Resource usage within limits - [ ] Security scan completed ### ✅ **Post-Deployment** - [ ] Service accessible via intended URLs - [ ] Monitoring alerts configured - [ ] Backup jobs scheduled - [ ] Documentation updated - [ ] Team notified of new service - [ ] Performance baseline established --- ## 🚨 Troubleshooting Deployment Issues ### 🔍 **Common Problems** #### **Container Won't Start** ```bash # Check logs docker-compose logs service-name # Check resource constraints docker stats # Verify image availability docker pull image:tag # Check port conflicts netstat -tulpn | grep :8080 ``` #### **Permission Issues** ```bash # Fix ownership (Synology) sudo chown -R 1026:100 /volume1/docker/service # Fix permissions sudo chmod -R 755 /volume1/docker/service ``` #### **Network Issues** ```bash # Check network connectivity docker exec service-name ping google.com # Verify DNS resolution docker exec service-name nslookup service-name # Check port binding docker port service-name ``` #### **Resource Constraints** ```bash # Check memory usage docker stats --no-stream # Check disk space df -h # Monitor resource limits docker exec service-name cat /sys/fs/cgroup/memory/memory.limit_in_bytes ``` --- ## 🔄 Update & Maintenance ### 📦 **Container Updates** ```bash # Update single service docker-compose pull docker-compose up -d # Update with Watchtower (automated) # Watchtower handles updates automatically for tagged containers ``` ### 🔧 **Configuration Changes** ```bash # Apply configuration changes docker-compose down # Edit configuration files docker-compose up -d # Rolling updates (zero downtime) docker-compose up -d --no-deps service-name ``` ### 🗄️ **Database Migrations** ```bash # Backup before migration docker exec db-container pg_dump -U user dbname > backup.sql # Run migrations docker-compose exec app python manage.py migrate # Verify migration docker-compose exec app python manage.py showmigrations ``` --- ## 📊 Performance Optimization ### ⚡ **Resource Tuning** ```yaml # Optimize for your workload deploy: resources: limits: memory: 2G # Set based on actual usage cpus: '1.0' # Adjust for CPU requirements reservations: memory: 512M # Guarantee minimum resources ``` ### 🗄️ **Storage Optimization** ```yaml # Use appropriate volume types volumes: # Fast storage for databases - /volume1/ssd/db:/var/lib/postgresql/data # Slower storage for archives - /volume1/hdd/archives:/archives:ro # Temporary storage - type: tmpfs target: /tmp tmpfs: size: 100M ``` ### 🌐 **Network Optimization** ```yaml # Optimize network settings networks: app-network: driver: bridge driver_opts: com.docker.network.bridge.name: br-app com.docker.network.driver.mtu: 1500 ``` --- ## 📋 Next Steps - **[Monitoring Setup](monitoring.md)**: Configure monitoring for your new service - **[Backup Configuration](backup.md)**: Set up automated backups - **[Troubleshooting Guide](../troubleshooting/common-issues.md)**: Common deployment issues - **[Service Categories](../services/categories.md)**: Find similar services for reference --- *Remember: Start simple, test thoroughly, and iterate based on real-world usage. Every service in this homelab started with this basic deployment pattern.*