Watchtower solves a common problem of how to update running Docker containers when a new image is released. Watchtower automatically “watches” your containers, periodically polling for new versions of their images and restarting them to run new releases.
In this article, we’ll show you how to use Watchtower to simplify container fleet management. We’ll also look at the advanced options you can use to customize Watchtower’s behavior.
Deployment of the Watchtower
The first step is to run a Watchtower instance inside a custom Docker container. Run the following command to download the Watchtower image and create the container:
$ docker run -d --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower
Your host’s Docker socket is mounted in a Watchtower container with
-v flag. This allows Watchtower to communicate with your host’s Docker daemon instance. This is necessary so that Watchtower can enumerate and run containers.
Watchtower can be used with a remote Docker host. Expose this host’s Docker daemon on a TCP port and then start Watchtower sa
DOCKER_HOST environment variables instead of socket binding:
$ docker run -d --name watchtower \ -e DOCKER_HOST="tcp://192.168.0.1:2375" \ containrrr/watchtower
If your Docker host is TLS protected, use Watchtower’s
--tlsverify tag and attach your certificates to the container
/etc/ssl/docker address book:
$ 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 on a Docker host. When a new Watchtower instance starts, it cleans up any pre-existing Watchtower containers. You can launch multiple instances by assigning them unique scopes, but this is usually not necessary in most deployments.
Using the Watchtower
Your Watchtower container will immediately start monitoring other containers on your Docker host. It will poll for image updates once every 24 hours and restart the containers when changes occur.
The new container will retain the same capabilities as the original one from which it was created. Port bindings, volume mounts, environment variables, and all other settings will be unaffected by the swap.
Watchtower is also dependency-aware: when containers are linked, Watchtower stops and starts them in a logical order. Services that depend on a particular container will be stopped before that container is updated and then resumed when a replacement is available. This ensures that your application does not encounter errors when its dependencies are updated.
The Watchtower sends a
SIGTERM signal to containers when it needs to stop for an update. You can change this signal by setting the container label. Here’s how to switch to
SIGHUP instead of
$ docker run -d --label=com.centurylinklabs.watchtower.stop-signal=SIGHUP my-image
Including 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 running a container that opts out of Watchtower updates using a label:
$ docker run -d --label=com.centurylinklabs.watchtower.enable=false my-image
It is also possible to whitelist containers that should be updated instead of opting out of those that should not be updated. Start the Watchtower with
--label-enable flag to enable this behavior:
$ docker run -d --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower --label-enable
Now use a label to mark some containers as eligible to receive updates:
$ docker run -d --label=com.centurylinklabs.watchtower.enable=true my-image
Life cycle hooks
Watchtower can optionally run scripts inside your containers when specific events occur. There are four hooks:
pre-check– Before Watchtower checks if an update is available for the container.
pre-update– After finding an update but before restarting the container.
post-update– After the update is complete.
post-check– After checking for container updates is complete.
Hooks are configured using container labels. The label value must be the path to the executable file inside the container image. This will be called every time the hook fires.
Here is a usage example
$ docker run -d --label=com.centurylinklabs.watchtower.lifecycle.pre-update="/backup.sh --create" my-image
Other hooks are configured similarly by substituting their name into the label.
Alerting and monitoring
Watchtower can send you notifications via email, Slack, Microsoft Teams, Gotify, and Shoutrrr when container updates are available. Each of these delivery mechanisms must be configured separately by setting environment variables in your Watchtower container.
Here is a basic example using Gmail:
$ docker run -d --name watchtower \ -e WATCHTOWER_NOTIFICATIONS=email -e [email protected] -e [email protected] -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 -e WATCHTO[email protected] -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=your_gmail_app_password -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower
Watchtower also supports operational mode, where it checks for container updates without using them. With this option, you can be notified when updates are available and then restart your containers yourself at the appropriate time.
Activate this mode with
$ docker run -d --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower --monitor-only
There is also a label that can be set on individual containers to log them into monitoring mode:
$ docker run -d --label=com.centurylinklabs.watchtower.monitor-only=true my-image
Change the update polling interval
The Watchtower checks for new images every 24 hours. This interval can be changed using
--interval flag or
WATCHTOWER_POLL_INTERVAL environment variable. 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 the cron syntax. This is accepted as
--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 pictures
Watchtower will leave the old version of the container images on your host after downloading the new one. Settings
--cleanup flag or
WATCHTOWER_CLEANUP Environment variable deletes old images after 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
Run on demand
Watchtower is designed to run as a long-running daemon that constantly monitors container updates. Sometimes you may want to manually check for new images on demand. You can do this using
--run-once command flag:
$ docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower --run-once
This will make one update attempt for all running containers. The Watchtower container will then stop and be removed.
Use of private registries
Watchtower needs credentials to check for image updates in private registries. One way to deliver 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
This approach comes with a caveat: update
config.json on your host will not necessarily be reflected inside the container. Commands like
docker login actually replace the file, instead of editing it directly. This creates a new inode and breaks the Docker connection.
Another way to provide Watchtower with registry credentials is hers
REPO_PASS variables. It will log in as a defined user before trying to download 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
Watchtower allows you to automate updates to Docker containers when new images are pushed to the registry. It is a highly customizable system that supports container blacklists and whitelists, advanced scheduling with cron syntax, and alerts delivered to several popular providers.
Optional configuration parameters enable additional features such as incremental restarts, updates on restarted 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.