Watchtower
A container-based solution for automating Docker container base image updates.
Quick start¶
Watchtower watches the Docker daemon it's pointed at, polls the registries of the running containers' images, and — when a digest changes — gracefully stops each stale container and recreates it with the same config (volumes, networks, env, command).
Pull from either registry; the images are identical:
docker pull openserbia/watchtower # Docker Hub
docker pull ghcr.io/openserbia/watchtower # GitHub Container Registry
Run it¶
docker run --detach \
--name watchtower \
--restart unless-stopped \
--volume /var/run/docker.sock:/var/run/docker.sock \
openserbia/watchtower \
--interval 60 --cleanup
services:
watchtower:
image: openserbia/watchtower:latest
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command:
- --interval=60
- --cleanup
- --label-enable
That's enough to start: Watchtower polls every 60 s and deletes old images after a successful update.
Scoping what it updates¶
By default, every container on the host is a candidate. To opt in only a chosen set, pass --label-enable and label the target containers:
docker run -d --label com.centurylinklabs.watchtower.enable=true my-app:latest
Omit the label to keep a container untouched (databases, stateful services, anything with a manual release process).
What's next¶
- Arguments — every flag and
WATCHTOWER_*env var - Container selection — include/exclude by label, scope, or name
- Notifications — Shoutrrr, email, Slack, Teams, Gotify
- Private registries — credentials via
config.json - HTTP API mode —
/v1/update,/v1/metrics,/v1/auditendpoints - Metrics — Prometheus exposition format + shipped Grafana dashboard
- Lifecycle hooks — pre/post scripts inside the target container
- Why this fork? — what openserbia/watchtower adds over upstream