# Watchtower Integration This guide explains how ComposeSync works with Watchtower and provides recommendations for using both tools together. ## Overview ComposeSync and Watchtower are complementary tools that serve different purposes: - **ComposeSync**: Updates Docker Compose configuration files - **Watchtower**: Updates Docker container images ## Key Differences | Feature | ComposeSync | Watchtower | |---------|-------------|------------| | **Purpose** | Updates compose files | Updates container images | | **Scope** | Configuration changes | Image updates | | **Method** | Downloads new compose files | Pulls new images | | **Safety** | Preserves overrides, rollback on failure | Automatic image updates | | **Control** | Version-controlled updates | Real-time updates | ## When to Use Each Tool ### Use ComposeSync When: - You want to update application configurations - You need to preserve custom overrides - You want version-controlled updates - You're managing complex multi-service stacks - You need rollback capabilities ### Use Watchtower When: - You want automatic image updates - You're running simple containers - You don't need configuration changes - You want real-time updates - You're using `latest` tags ## Integration Strategies ### Strategy 1: ComposeSync Only (Recommended) Use ComposeSync for both configuration and image updates: ```toml # Global settings [global] UPDATE_INTERVAL_SECONDS = 3600 KEEP_VERSIONS = 10 DRY_RUN = false # Stack with specific image versions [immich] URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml" PATH = "/opt/composesync/stacks/immich" TOOL = "wget" ``` **Benefits:** - Full control over updates - Configuration and images updated together - Automatic rollback on failures - Preserves your customizations ### Strategy 2: Watchtower Only Use Watchtower for automatic image updates: ```yaml # docker-compose.yml version: '3.8' services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_POLL_INTERVAL=3600 - WATCHTOWER_CLEANUP=true restart: unless-stopped ``` **Benefits:** - Real-time image updates - Simple setup - Automatic cleanup ### Strategy 3: Hybrid Approach Use both tools for different purposes: ```toml # ComposeSync for configuration updates [global] UPDATE_INTERVAL_SECONDS = 86400 # Daily config updates KEEP_VERSIONS = 10 DRY_RUN = false [immich] URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml" PATH = "/opt/composesync/stacks/immich" TOOL = "wget" ``` ```yaml # Watchtower for image updates version: '3.8' services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_POLL_INTERVAL=3600 # Hourly image updates - WATCHTOWER_CLEANUP=true - WATCHTOWER_LABEL_ENABLE=true restart: unless-stopped ``` ## Best Practices ### 1. Avoid Conflicts **Don't use both tools on the same services** - this can cause conflicts and unexpected behavior. ### 2. Use Specific Image Tags When using ComposeSync, prefer specific image tags over `latest`: ```yaml # Good: Specific version services: immich-server: image: ghcr.io/immich-app/immich-server:v1.75.0 # Avoid: Latest tag services: immich-server: image: ghcr.io/immich-app/immich-server:latest ``` ### 3. Configure Update Intervals Set appropriate intervals for each tool: ```toml # ComposeSync: Less frequent config updates [global] UPDATE_INTERVAL_SECONDS = 86400 # Daily [immich] URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml" PATH = "/opt/composesync/stacks/immich" TOOL = "wget" ``` ```yaml # Watchtower: More frequent image updates services: watchtower: environment: - WATCHTOWER_POLL_INTERVAL=3600 # Hourly ``` ### 4. Use Labels for Control When using Watchtower, use labels to control which containers are updated: ```yaml # docker-compose.yml version: '3.8' services: immich-server: image: ghcr.io/immich-app/immich-server:v1.75.0 labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped database: image: postgres:15 labels: - "com.centurylinklabs.watchtower.enable=false" # Don't auto-update restart: unless-stopped ``` ## Migration Scenarios ### From Watchtower to ComposeSync If you're currently using Watchtower and want to switch to ComposeSync: 1. **Stop Watchtower:** ```bash docker compose down watchtower ``` 2. **Configure ComposeSync:** ```toml [global] UPDATE_INTERVAL_SECONDS = 3600 KEEP_VERSIONS = 10 DRY_RUN = false [your-stack] URL = "https://your-source.com/docker-compose.yml" PATH = "/opt/composesync/stacks/your-stack" TOOL = "wget" ``` 3. **Create override file:** ```bash sudo nano /opt/composesync/stacks/your-stack/docker-compose.override.yml ``` 4. **Start ComposeSync:** ```bash sudo systemctl start composesync ``` ### From ComposeSync to Watchtower If you want to switch from ComposeSync to Watchtower: 1. **Stop ComposeSync:** ```bash sudo systemctl stop composesync sudo systemctl disable composesync ``` 2. **Deploy Watchtower:** ```yaml version: '3.8' services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_POLL_INTERVAL=3600 - WATCHTOWER_CLEANUP=true restart: unless-stopped ``` 3. **Update your compose files to use `latest` tags:** ```yaml services: your-app: image: your-app:latest ``` ## Troubleshooting ### Conflicts Between Tools If you experience conflicts: ```bash # Check which tool is managing your containers docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" # Check ComposeSync logs sudo journalctl -u composesync -f # Check Watchtower logs docker logs watchtower ``` ### Unexpected Updates If containers are updating unexpectedly: ```bash # Check ComposeSync configuration cat /opt/composesync/config.toml # Check Watchtower configuration docker inspect watchtower | grep -A 10 "Env" # Check container labels docker inspect your-container | grep -A 5 "Labels" ``` ### Performance Issues If you experience performance issues: ```bash # Check update frequency grep "UPDATE_INTERVAL_SECONDS" /opt/composesync/config.toml # Check Watchtower interval docker inspect watchtower | grep "WATCHTOWER_POLL_INTERVAL" # Monitor resource usage docker stats ``` ## Recommendations ### For Production Environments **Use ComposeSync** for production environments because: - Better control over updates - Automatic rollback on failures - Preserves your customizations - Version-controlled updates - Better monitoring and logging ### For Development Environments **Use Watchtower** for development environments because: - Faster iteration - Real-time updates - Simpler setup - Less configuration overhead ### For Mixed Environments **Use the hybrid approach** with: - ComposeSync for critical production stacks - Watchtower for development and testing stacks - Clear separation of responsibilities ## Example Configurations ### Production Setup (ComposeSync Only) ```toml # /opt/composesync/config.toml [global] UPDATE_INTERVAL_SECONDS = 86400 # Daily updates KEEP_VERSIONS = 15 DRY_RUN = false NOTIFICATION_WEBHOOK_URL = "https://your-webhook.com/endpoint" [immich] URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml" PATH = "/opt/composesync/stacks/immich" TOOL = "wget" [portainer] URL = "https://github.com/portainer/portainer-compose.git" PATH = "/opt/composesync/stacks/portainer" TOOL = "git" GIT_SUBPATH = "compose/docker-compose.yml" GIT_REF = "main" ``` ### Development Setup (Watchtower Only) ```yaml # docker-compose.yml version: '3.8' services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_POLL_INTERVAL=1800 # 30 minutes - WATCHTOWER_CLEANUP=true - WATCHTOWER_LABEL_ENABLE=true restart: unless-stopped dev-app: image: your-dev-app:latest labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ``` ### Hybrid Setup ```toml # ComposeSync for production stacks [global] UPDATE_INTERVAL_SECONDS = 86400 KEEP_VERSIONS = 10 [production-app] URL = "https://github.com/user/production-app.git" PATH = "/opt/composesync/stacks/production" TOOL = "git" GIT_REF = "main" ``` ```yaml # Watchtower for development stacks services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_POLL_INTERVAL=3600 - WATCHTOWER_CLEANUP=true - WATCHTOWER_LABEL_ENABLE=true restart: unless-stopped dev-app: image: your-dev-app:latest labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ```