01The Update Problem
Running 20+ Docker containers means 20+ images that need updating. Security patches, bug fixes, and new features are released constantly, and falling behind on updates is a real security risk. But manually checking for updates, pulling new images, and restarting containers across your entire stack is tedious.
Watchtower solves this by monitoring your running containers and automatically updating them when a new image is pushed to the registry. I've run it for two years across my home lab and it's saved me hours of manual maintenance.
But automatic updates need guardrails. You don't want Watchtower blindly updating your production database at 2 PM on a Tuesday. This guide covers the setup and the strategies that make auto-updates safe.
02Basic Watchtower Setup
Watchtower itself runs as a Docker container. Add it to its own compose file:
[docker-compose.yml]
1services: 2 watchtower: 3 image: containrrr/watchtower:latest4 container_name: watchtower5 restart: unless-stopped6 volumes: 7 - /var/run/docker.sock:/var/run/docker.sock8 environment: 9 - WATCHTOWER_CLEANUP=true10 - WATCHTOWER_SCHEDULE=0 0 4 * * * # 4 AM daily11 - WATCHTOWER_NOTIFICATIONS=shoutrrr12 - WATCHTOWER_NOTIFICATION_URL=telegram://token@telegram?channels=chatidAlways set WATCHTOWER_CLEANUP=true to automatically remove old images after updates. Without this, outdated images accumulate and waste disk space.
03Selective Update Strategies
The safest approach is monitor-only mode combined with labels that control which containers get auto-updated:
Set WATCHTOWER_LABEL_ENABLE=true to make Watchtower only update containers with the com.centurylinklabs.watchtower.enable=true label. This gives you per-container control.
For critical services like databases, I use monitor-only mode: Watchtower checks for updates and notifies me, but doesn't apply them automatically. I update databases manually after reviewing changelogs and backing up.
For low-risk services like dashboards, monitoring tools, and media servers, I let Watchtower auto-update freely. If something breaks, I can roll back to the previous image quickly.
[docker-compose.yml]
1# In your service's docker-compose.yml:2services: 3 homepage: 4 image: ghcr.io/gethomepage/homepage:latest5 labels: 6 - "com.centurylinklabs.watchtower.enable=true" # Auto-update78 postgres: 9 image: postgres:16-alpine10 labels: 11 - "com.centurylinklabs.watchtower.enable=false" # Manual only04Rollback Strategy
Before relying on auto-updates, make sure you can roll back. If an update breaks a service:
If you pinned to a major version tag (postgres:16), the old image layers are usually still cached locally. Run docker compose pull with the specific version to revert.
If you use :latest tags, Watchtower removes old images by default. To keep rollback capability, set WATCHTOWER_CLEANUP=false or use the --keep option to retain the previous image version.
The safest approach: always pin critical services to specific versions (postgres:16.3-alpine, not postgres:latest) and exclude them from Watchtower. Update them manually on your schedule after checking release notes.
Browse our homelab category for more automation and maintenance tools that complement Watchtower.
Never auto-update database containers. Database image updates can trigger migrations or format changes that require manual intervention. Always update databases manually with a fresh backup.