August 23, 2026
Watchtower and the Risks of Automated Container Updates
Watchtower monitors running Docker containers and updates their images automatically. Convenient for a homelab, yet unattended updates without scoping can quietly introduce breaking changes. This post covers how it works, risk controls, and its limits.
Watchtower is an automation utility that monitors running Docker containers and updates them whenever new base images are pushed to image registries. In a homelab, most services run on floating :latest tags and manual patching is easy to postpone; Watchtower closes that gap while opening a new one: updates that happen with nobody watching. This is a hands-on note about how it works, how to deploy it, and the risks worth controlling.
Why automate image updates
The real problem Watchtower solves is a chore that keeps getting deferred: docker compose pull followed by recreating every service by hand. With a dozen services, image versions keep aging and upstream security fixes never reach the containers. Watchtower replaces that weekly ritual: it polls registries on a schedule and swaps images without requiring SSH access to the server each week.
The automation ships as a single small Go container and is designed for exactly this context — the official README targets homelabs, media centers, and local dev environments, and explicitly not production.
How Watchtower operates
- Watchtower runs as a container connected to the Docker API through
/var/run/docker.sock. - By default it polls registries every
86400seconds (24 hours). For each monitored container it compares the local image digest against the registry digest (a HEAD request); nothing is pulled when they match. - When the digest differs, the new image is pulled, the old container is gracefully stopped, and the container is recreated with identical execution parameters and volume mounts.
- With
--cleanup, the previous image is removed after the update.
Scheduling can be tuned: --interval takes seconds, or --schedule takes a 6-field cron expression — exactly one of them, not both. --run-once performs a single update attempt and exits; --rolling-restart restarts one container at a time instead of all at once.
Deployment via Docker Compose
Standard setup featuring old image cleanup (--cleanup) and a 24-hour poll interval (86400 seconds):
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
command: ["--cleanup", "--interval", "86400"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock
The socket mount is mandatory: without it Watchtower cannot reach the Docker API. For private registries, provide REPO_USER and REPO_PASS environment variables, or mount $HOME/.docker/config.json into the container at /config.json. Most flags also have WATCHTOWER_* environment variable equivalents, e.g. WATCHTOWER_POLL_INTERVAL replaces --interval.
Controlling the Risk of Unattended Updates
An update loop without scoping is a breaking change waiting to happen with no warning. The mitigations I rely on:
- Label scoping. Pass
--label-enableso Watchtower only processes containers that explicitly opt in:labels: - "com.centurylinklabs.watchtower.enable=true" - Exclude stateful infrastructure. Databases (PostgreSQL, MySQL) and other core control planes should stay out of unattended updates — either by withholding the label or using
--disable-containerswith a comma-separated name list. - Monitor-only mode.
--monitor-onlymakes Watchtower check and notify without updating; it can be applied per container with thecom.centurylinklabs.watchtower.monitor-only=truelabel. Useful to observe before trusting automation. - Notifications. Set
--notification-url(Shoutrrr) so every update or failure is recorded to a supported chat service — important when updates run without supervision. - Graceful shutdown budget. The default wait before a forced stop is 10 seconds;
--stop-timeout 30sgives applications more time to shut down cleanly.
Recovery: updating is not backup. Named volumes are left untouched, but if a fresh image misbehaves, rolling back means pinning to the previous image tag or commit. Keeping compose files in git ensures the old configuration can always be restored.
Limitations and Trade-offs
- Breaking changes behind
:latest. Floating tags make no compatibility promises; a container that was healthy yesterday may fail to start after the recreate. - Officially not for production. The project README explicitly does not recommend Watchtower for commercial or production environments; Kubernetes or a proper release pipeline is the intended answer there.
- Full docker.sock access. Watchtower needs complete control over the Docker daemon; if the Watchtower image or a registry is compromised, the blast radius is effectively root on the host.
- Registry rate limits. Polling and pulling from Docker Hub anonymously can hit rate limits, especially when many images change at once.
- Maintenance status. The official repository declares the project no longer maintained (see discussion #2135 in the repo); community forks keep shipping releases, but the situation is worth planning around.
Conclusion
Watchtower remains a practical tool for a homelab: security patches actually reach non-critical services without manual work, as long as scope is label-based, stateful containers are excluded, and notifications are wired up. It is not an answer for production, and automation does not reduce backup obligations — it closes one routine chore while introducing risks that must be managed deliberately.
