Docker is a popular containerization platform that allows you to easily package, distribute, and run applications in lightweight, portable containers. In light of this, one of the essential tasks in Docker container management is keeping container images up-to-date with the latest software patches, security fixes, and feature updates.
In this article, we introduce you to an exciting tool called “Watchtower,” which automates updating Docker container images. We will explore what Watchtower is, how it works, and how it can simplify your Docker workflow. So, let’s get started!
What is Watchtower?
Updating Docker container images can be a time-consuming and error-prone task, especially when managing a large number of containers across multiple hosts.
How do you update your Docker images so far?
docker stop <container_name>
docker rm <container_name>
docker pull <container_image>
docker run <container_name>
Code language: HTML, XML (xml)
However, this approach can become a real challenge if you have dozens, not to mention hundreds of Docker images. What if you have multiple Dockerized hosts? You’ll agree that then the task seems almost impossible. This is where Watchtower comes to the rescue.
Watchtower is a lightweight, open-source container management tool that automates updating Docker container images. It monitors your Docker environment for changes in the available image versions and automatically pulls and updates containers with the latest images.
With Watchtower, you can keep your containers up-to-date without manual intervention, ensuring your applications run with the latest features and security patches.
How Watchtower Works?
Watchtower periodically checks the remote Docker image registry, such as Docker Hub or a private container registry, for updates to the container images currently running on your system.
When a new version of an image is available, Watchtower pulls the updated image. Then, it gracefully restarts the corresponding containers with the new image using the same options that were used when it was deployed initially.
By default, Watchtower checks every 86400 seconds (24 hours) if there are updates for the Docker images running containerized apps. According to your needs, however, the “WATCHTOWER_POLL_INTERVAL” and “WATCHTOWER_SCHEDULE” environment variables can change this interval.
In addition, Watchtower also provides options for scheduling updates, rolling updates, and configuring notifications, allowing you to customize the update process according to your requirements.
How to Use Watchtower
Watchtower is distributed as a Docker container, making installation as simple as possible. Because the app needs to interact with the Docker API to monitor the running containers, you need to mount the host’s “/var/run/docker.sock” into the Watchtower container using the “-v (–volume)” option.
So, you can run it with the following Docker command:
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
If you prefer to run Watchtower using Docker Compose, create an appropriate “docker-compose.yaml” file and place the following content in it:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Code language: JavaScript (javascript)
Then, fire up the container using the command below:
docker-compose up -d
If you need further guidance on how to use Docker Compose, our in-depth guide on the topic will significantly help.
That’s it! Your Watchtower container is started and begins monitoring all other running containers on your host, including itself, for Docker image updates.
If you check the Watchtower container logs (docker logs watchtower
), you will see all its actions.
Of course, the necessary time must have elapsed for the information to accumulate, depending on the checking interval you have set.
Changing the Polling Interval
As previously stated, the default period for checking for new Docker images is 86400 seconds (24 hours). Watchtower gives us two options to control how frequently it will poll for new images, “WATCHTOWER_POLL_INTERVAL” and “WATCHTOWER_SCHEDULE.”
You can use whichever one you want, but not both simultaneously. So, let us show you how to use them.
Let’s say we want to set the default time interval for checking updates for new Docker images to 6 hours (21600 seconds). In that case, the Docker command we use to start Watchtower would be:
docker run -d \
--name watchtower \
-e WATCHTOWER_POLL_INTERVAL=21600 \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
Using Docker Compose, the “docker-compose.yaml” file would look like this:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_POLL_INTERVAL: 21600
Code language: JavaScript (javascript)
The other environment variable is to use “WATCHTOWER_SCHEDULE,” which uses theย Cron format, but instead of five fields, it uses six, adding one at the beginning for the seconds.
For example, set Watchtower to check every day at 4 AM for updated images, our Docker command would be:
docker run -d \
--name watchtower \
-e WATCHTOWER_SCHEDULE="0 0 4 * * *" \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
The Docker Compose equivalent is:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_SCHEDULE: "0 0 4 * * *"
Code language: JavaScript (javascript)
Set Time Zone
If you are using scheduling like the one shown above, it is recommended to set a time zone. This guarantees that the run time matches what you want. Otherwise, Watchtower will use UTC as the default time zone.
To find the correct value, consult this list, find your location, and use the value in the โTZโ variable, for example, โAmerica/New_York.โ
docker run -d \
--name watchtower \
-e WATCHTOWER_SCHEDULE="0 0 4 * * *" \
-e TZ=America/New_York
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
The Docker Compose equivalent is:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_SCHEDULE: "0 0 4 * * *"
TZ: America/New_York
Code language: JavaScript (javascript)
Cleaning Up Old Docker Images
By default, Watchtower will not remove old Docker images when it downloads a new one. This can result in hundreds of orphaned ones taking up disk space over time.
To avoid this, you can run Watchtower with the “WATCHTOWER_CLEANUP” environment variable set to “true,” which will remove the old image after restarting a container with a new one.
docker run -d \
--name watchtower \
-e WATCHTOWER_CLEANUP=true \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
Using Docker Compose, the “docker-compose.yaml” file would look like this:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_CLEANUP: true
Code language: JavaScript (javascript)
Excluding and Including Containers
By default, Watchtower monitors all containers. However, you may only want specific containers to be automatically updated. To achieve this, you must run those containers with the “com.centurylinklabs.watchtower.enable” label set to “true.”
docker run -d --label=com.centurylinklabs.watchtower.enable=true someimage
Code language: JavaScript (javascript)
Then, run Watchtower with the “WATCHTOWER_LABEL_ENABLE” environment variable set to “true“:
docker run -d \
--name watchtower \
-e WATCHTOWER_LABEL_ENABLE=true \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
If you’re a Docker Compose user:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_LABEL_ENABLE: true
Code language: JavaScript (javascript)
The opposite is also possible. For example, to mark only specific containers not to be monitored for Docker image updates, start them with the label “com.centurylinklabs.watchtower.enable=false” and then run Watchtower without setting the “WATCHTOWER_LABEL_ENABLE” environment variable.
Keeping Track of the Watchtower’s Actions
However, the automatic updating of Docker app images also poses some risks. Thatโs why we need to keep track of whatโs happening on the server and what actions Watchtower takes with our dockerized applications.
A possible approach can be to inspect its logs regularly using the docker logs watchtower
command. However, this requires regular engagement, and experience has shown that it is not the most reliable solution.
A significantly better way to accomplish this is to instruct Watchtower to email us when it acts. In that case, the Docker command we use to start Watchtower would be:
docker run -d --name watchtower \
-e WATCHTOWER_NOTIFICATIONS=email \
-e WATCHTOWER_NOTIFICATIONS_HOSTNAME="Lab1 Server" \
-e [email protected] \
-e [email protected] \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.yourdomain.com \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=fromaddress@yourdomain.com \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=yourpassword \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
If you’re a Docker Compose user:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_NOTIFICATIONS: email
WATCHTOWER_NOTIFICATIONS_HOSTNAME: "Lab1 Server"
WATCHTOWER_NOTIFICATION_EMAIL_FROM: [email protected]
WATCHTOWER_NOTIFICATION_EMAIL_TO: [email protected]
WATCHTOWER_NOTIFICATION_EMAIL_SERVER: mail.yourdomain.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: 587
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER: [email protected]
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD: yourpassword
Code language: JavaScript (javascript)
Of course, an SMTP server and the relevant credentials are required for this to work. In addition, don’t forget to replace all environment variables except “WATCHTOWER_NOTIFICATIONS: email” in the examples above with the appropriate values for your case.
Immediately after starting the container, you should receive a message in your mail similar to the one shown below.
But let’s go one step further. Sending notifications can be nicely combined with the Watchtower’s “WATCHTOWER_MONITOR_ONLY” environment variable; as a result, none of the containers will be automatically updated, and we will only receive notifications about new Docker image updates that become available.
With this information, we can decide whether to perform the update manually and at the most appropriate time.
To achieve this, our Docker command would be:
docker run -d --name watchtower \
-ะต WATCHTOWER_MONITOR_ONLY=true \
-e WATCHTOWER_NOTIFICATIONS=email \
-e WATCHTOWER_NOTIFICATIONS_HOSTNAME="Lab1 Server" \
-e [email protected] \
-e [email protected] \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.yourdomain.com \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=fromaddress@yourdomain.com \
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=yourpassword \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Code language: JavaScript (javascript)
Docker Compose users must perform the following:
version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_MONITOR_ONLY: true
WATCHTOWER_NOTIFICATIONS: email
WATCHTOWER_NOTIFICATIONS_HOSTNAME: "Lab1 Server"
WATCHTOWER_NOTIFICATION_EMAIL_FROM: [email protected]
WATCHTOWER_NOTIFICATION_EMAIL_TO: [email protected]
WATCHTOWER_NOTIFICATION_EMAIL_SERVER: mail.yourdomain.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: 587
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER: [email protected]
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD: yourpassword
Code language: JavaScript (javascript)
Conclusion
There are several benefits to using Watchtower in your Docker workflow. First, it helps you keep your containers secure by automatically updating them with the latest security fixes and patches. This helps mitigate the risk of running containers with known vulnerabilities, which malicious actors can exploit.
Second, Watchtower simplifies updating container images, saving you time and effort compared to manual updates. It also reduces the risk of human error, which can occur when manually updating containers.
Finally, Watchtower provides flexibility and customization options, allowing you to configure the update process according to your specific needs and preferences.
Of course, you can use a whole host of other options to tailor Watchtower to your needs. To explore them in depth, visit the project’s website.
We hope that we were helpful to you. Any comments or suggestions are welcome in the comments section below.