Automatically Update Your Docker Containers with Watchtower
A handy utility for automating your Docker container updates.
Imagine this: You’ve deployed a handful of Docker containers to power your favorite applications, maybe a self-hosted Nextcloud for your files, a Pi-hole for ad-blocking, or even a media server like Jellyfin.
Everything is running like a charm, but then you hit a common snag: keeping those containers updated.
When a new image is released, you’ll need to manually pull it, stop the running container, recreate it with the updated image, and hope everything works as expected.
Multiply that by the number of containers you’re running, and it’s clear how this quickly becomes a tedious and time-consuming chore.
But there’s more at stake than just convenience. Skipping updates or delaying them for too long can lead to outdated software running in your containers, which often means unpatched vulnerabilities.
These can become a serious security risk, especially if you’re hosting services exposed to the internet.
This is where Watchtower steps in, a tool designed to take the hassle out of container updates by automating the entire process.
Whether you’re running a homelab or managing a production environment, Watchtower ensures your containers are always up-to-date and secure, all with minimal effort on your part.
What is Watchtower?
Watchtower is an open-source tool that automatically monitors your Docker containers and updates them whenever a new version of their image is available.
It keeps your setup up-to-date, saving time and reducing the risk of running outdated containers.
But it’s not just a "set it and forget it" solution, it’s also highly customizable, allowing you to tailor its behavior to fit your workflow.
Whether you prefer full automation or staying in control of updates, Watchtower has you covered.
How does it work?
Watchtower works by periodically checking for updates to the images of your running containers. When it detects a newer version, it pulls the updated image, stops the current container, and starts a new one using the updated image.
The best part? It maintains your existing container configuration, including port bindings, volume mounts, and environment variables.
If your containers depend on each other, Watchtower handles the update process in the correct order to avoid downtime.
Deploying watchtower
Since you’re reading this article, I’ll assume you already have some sort of homelab or Docker setup where you want to automate container updates. That means I won’t be covering Docker installation here.
When it comes to deploying Watchtower, it can be done in two ways:
Docker run
If you’re just trying it out or want a straightforward deployment, you can run the following command:
docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
This will spin up a Watchtower container that monitors your running containers and updates them automatically.
But here’s the thing, I’m not a fan of the docker run
command.
It’s quick, sure, but I prefer stack approach rather than cramming everything into a single command.
Docker compose
If you facny using Docker Compose to run Watchtower, here’s a minimal configuration that replicates the docker run
command above:
version: "3.8"
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
To start Watchtower using this configuration, save it as docker-compose.yml
and run:
docker-compose up -d
This will give you the same functionality as the docker run
command, but in a cleaner, more manageable format.
Customizing watchtower with environment variables
Running Watchtower plainly is all good, but we can make it even better with environment variables and command arguments.
Personally, I don’t like giving full autonomy to one service to automatically make changes on my behalf.
Since I have a pretty decent homelab running crucial containers, I prefer using Watchtower to notify me about updates rather than updating everything automatically.
This ensures that I remain in control, especially for containers that are finicky or require a perfect pairing with their databases.
Sneak peak into my homelab
Take a look at my homelab setup: it’s mostly CMS containers for myself and for clients, and some of them can behave unpredictably if not updated carefully.
So instead of letting Watchtower update everything, I configure it to provide insights and alerts, and then I manually decide which updates to apply.
To achieve this, we’ll add the following environment variables to our Docker Compose file:
Environment Variable | Description |
---|---|
WATCHTOWER_CLEANUP | Removes old images after updates, keeping your Docker host clean. |
WATCHTOWER_POLL_INTERVAL | Sets how often Watchtower checks for updates (in seconds). One hour (3600 seconds) is a good balance. |
WATCHTOWER_LABEL_ENABLE | Updates only containers with specific labels, giving you granular control. |
WATCHTOWER_DEBUG | Enables detailed logs, which can be invaluable for troubleshooting. |
WATCHTOWER_NOTIFICATIONS | Configures the notification method (e.g., email) to keep you informed about updates. |
WATCHTOWER_NOTIFICATION_EMAIL_FROM | The email address from which notifications will be sent. |
WATCHTOWER_NOTIFICATION_EMAIL_TO | The recipient email address for update notifications. |
WATCHTOWER_NOTIFICATION_EMAIL_SERVER | SMTP server address for sending notifications. |
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT | Port used by the SMTP server (commonly 587 for TLS). |
WATCHTOWER_NOTIFICATION_EMAIL_USERNAME | SMTP server username for authentication. |
WATCHTOWER_NOTIFICATION_EMAIL_PASSWORD | SMTP server password for authentication. |
Here’s how the updated docker-compose.yml
file would look:
version: "3.8"
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: always
environment:
WATCHTOWER_CLEANUP: "true"
WATCHTOWER_POLL_INTERVAL: "3600"
WATCHTOWER_LABEL_ENABLE: "true"
WATCHTOWER_DEBUG: "true"
WATCHTOWER_NOTIFICATIONS: "email"
WATCHTOWER_NOTIFICATION_EMAIL_FROM: "[email protected]"
WATCHTOWER_NOTIFICATION_EMAIL_TO: "[email protected]"
WATCHTOWER_NOTIFICATION_EMAIL_SERVER: "smtp.example.com"
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: "587"
WATCHTOWER_NOTIFICATION_EMAIL_USERNAME: "your_email_username"
WATCHTOWER_NOTIFICATION_EMAIL_PASSWORD: "your_email_password"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Once you run the Watchtower container for the first time, you'll receive an initial email confirming that the service is up and running.
Here's an example of what that email might look like:
After some time, as Watchtower analyzes your setup and scans the running containers, it will notify you if it detects any updates available for your containers.
These notifications are sent in real-time and look something like this:
This feature ensures you're always in the loop about potential updates without having to check manually.
Final thoughts
I’m really impressed by Watchtower and have been using it for a month now.
I recommend, if possible, to play around with it in an isolated environment first, that’s what I did before deploying it in my homelab.
The email notification feature is great, but my inbox now looks totally filled with Watchtower emails, so I might create a rule to manage them better. Overall, no complaints so far! I find it better than the Docker Compose method we discussed earlier.
What about you? What do you use to update your containers?
If you’ve tried Watchtower, share your experience, anything I should be mindful of?
Let us know in the comments!
I'm definitely not a nerd, perhaps a geek who likes to tinker around with whatever tech I get my hands on. Figuring things out on my own gives me joy. BTW, I don't use Arch.