Watchtower solves the common problem of how to update running Docker containers when a new image releases. Watchtower automatically “watches” your containers, periodically polls for new versions of their images, and restarts them so they’re running the new release.
In this article we’ll show how to use Watchtower to simplify your container fleet administration. We’ll also look at the advanced options you can use to customize Watchtower’s behavior.
Deploying Watchtower
The first step is to start a Watchtower instance inside its own Docker container. Run the following command to download the Watchtower image and create a container:
$ docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
Your host’s Docker socket is mounted into the Watchtower container with the -v
flag. This allows Watchtower to interact with your host’s Docker daemon instance. It’s required so Watchtower can enumerate and start containers.
It’s possible to use Watchtower with a remote Docker host. Expose that host’s Docker daemon on a TCP port, then start Watchtower with a DOCKER_HOST
environment variable instead of a socket bind:
$ docker run -d --name watchtower -e DOCKER_HOST="tcp://192.168.0.1:2375" containrrr/watchtower
If your Docker host is protected with TLS, use Watchtower’s --tlsverify
flag and mount your certificates into the container’s /etc/ssl/docker
directory:
$ docker run -d --name watchtower -e DOCKER_HOST="tcp://192.168.0.1:2375" -e DOCKER_CERT_PATH=/etc/ssl/docker -v ./certs:/etc/ssl/docker containrrr/watchtower --tlsverify
Watchtower is designed to run once per Docker host. When a new Watchtower instance starts, it’ll clean up any other Watchtower containers already exist. You can run multiple instances by assigning them each unique scopes but this isn’t usually necessary in most deployments.
Using Watchtower
Your Watchtower container immediately starts monitoring the other containers on your Docker host. It’ll poll for image updates once every 24 hours and restart your containers when changes occur.
New container retain the same options as the original that they’re created from. Port binds, volume mounts, environment variables, and any other settings will all be intact on the replacement.
Watchtower is also dependency-aware: when containers are linked together, Watchtower will stop and start them in a logical order. Services that depend on a particular container will be stopped before that container’s updated, then brought back up after the replacement’s available. This ensures your applications don’t encounter errors while their dependencies are updating.
Watchtower sends a SIGTERM
signal to containers when it needs them to stop for an update. You can change this signal by setting a label on your containers. Here’s how to switch to SIGHUP
instead of SIGTERM
:
$ docker run -d --label=com.centurylinklabs.watchtower.stop-signal=SIGHUP my-image
Excluding and Including Containers
You can customize which containers are monitored using a combination of Watchtower command arguments and Docker labels on your individual containers. Here’s an example of starting a container which is opted-out of Watchtower updates using a label:
$ docker run -d --label=com.centurylinklabs.watchtower.enable=false my-image
It’s also possible to whitelist the containers that should be updated, instead of opting out the ones that shouldn’t. Start Watchtower with the --label-enable
flag to activate this behavior:
$ docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --label-enable
Now use the label to designate some containers as eligible to receive updates:
$ docker run -d --label=com.centurylinklabs.watchtower.enable=true my-image
Lifecycle Hooks
Watchtower can optionally run scripts inside your containers when specific events occur. Four hooks are available:
pre-check
– Before Watchtower checks whether an update is available for the container.pre-update
– After an update has been found but before the container’s restarted.post-update
– After an update has been completed.post-check
– After a container’s check for updates has been completed.
Hooks are configured using container labels. The value of the label needs to be the path to an executable inside the container image. This will be called each time the hook fires.
Here’s an example of using the pre-update
hook:
$ docker run -d --label=com.centurylinklabs.watchtower.lifecycle.pre-update="/backup.sh --create" my-image
The other hooks are configured similarly by substituting their name into the label.
Notifications and Monitoring
Watchtower can send you notifications over email, Slack, Microsoft Teams, Gotify and Shoutrrr when container updates become available. Each of these delivery mechanisms needs to be configured separately by setting environment variables in your Watchtower container.
Here’s a basic example that uses Gmail:
$ docker run -d --name watchtower -e WATCHTOWER_NOTIFICATIONS=email -e WATCHTOWER_NOTIFICATION_EMAIL_FROM=you@gmail.com -e WATCHTOWER_NOTIFICATION_EMAIL_TO=you@gmail.com -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=you@gmail.com -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=your_gmail_app_password -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
Watchtower also supports an operating mode where it checks for container updates without applying them. You can use this to be notified when updates are available, then restart your containers yourself at a convenient time.
Activate this mode with the --monitor-only
flag:
$ docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --monitor-only
There’s also a label that can be set on individual containers to opt them into the monitoring mode:
$ docker run -d --label=com.centurylinklabs.watchtower.monitor-only=true my-image
Changing the Update Polling Interval
Watchtower checks for new images every 24 hours. This interval can be changed with the --interval
flag or WATCHTOWER_POLL_INTERVAL
environment variable. It accepts a value in seconds.
# Update every hour $ docker run -d --name watchtower -e WATCHTOWER_POLL_INTERVAL=3600 -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
Alternatively you can define a fixed polling schedule using cron syntax. This is accepted as the --schedule
flag or WATCHTOWER_SCHEDULE
environment variable.
# Update every five minutes $ docker run -d --name watchtower -e WATCHTOWER_SCHEDULE="*/5 * * * *" -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
Cleaning Up Old Images
Watchtower leaves the old version of container images on your host after a new one is pulled. Setting the --cleanup
flag or WATCHTOWER_CLEANUP
environment variable will delete old images after an update. This can significantly free up disk space over time.
$ docker run -d --name watchtower -e WATCHTOWER_CLEANUP=true -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
Running On-Demand
Watchtower is designed to run as a long-lived daemon that continually monitors containers for updates. Sometimes you might want to manually check for new images on-demand. You can do this with the --run-once
command flag:
$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once
This will perform a single update attempt for all your running containers. The Watchtower container will then stop and be removed.
Using Private Registries
Watchtower needs authentication details to check for updates to images in private registries. One way to supply them is by mounting your Docker config.json
file to /config.json
in your Watchtower container:
$ docker run -d --name watchtower -v $HOME:/.docker/config.json:/config.json -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
There’s a caveat with this approach: updates to config.json
on your host won’t necessarily be reflected inside the container. Commands like docker login
actually replace the file, instead of directly editing it. This creates a new inode, breaking the Docker bind mount.
Another way to provide registry credentials to Watchtower is its REPO_USER
and REPO_PASS
variables. It’ll login as the defined user before trying to pull your images.
$ docker run -d --name watchtower -e REPO_USER=demo-user -e REPO_PASS=users-password -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
Conclusion
Watchtower lets you automate Docker container updates when new images are pushed to a registry. It’s a highly customizable system that supports container blacklists and whitelists, advanced scheduling with cron syntax, and notifications delivered to several popular providers.
Optional configuration parameters expose further functionality, such as rolling restarts, updates of restarting and stopped containers, and support for exposing metrics that give you another way to visualize update activity. This makes Watchtower a good choice for managing a busy set of production Docker containers.