The Ultimate Guide to Containrrr/Watchtower: Automate Docker Updates Like a Pro

containrrr/watchtower

If you have ever spent a Saturday afternoon manually pulling new images for twenty different Docker containers, you know the struggle is real. You check the hub, you see a new version of Nginx or Home Assistant, you pull it, you stop the old container, you remove it, and then you recreate it. It is a tedious dance that we all do when we first start self-hosting. But as your “homelab” or production environment grows, this becomes an impossible task to keep up with. This is exactly where containrrr/watchtower comes into the picture. It is a tiny but incredibly powerful tool that monitors your running Docker containers and automatically updates them to the latest version of their image.

I remember the first time I set up a media server. I had about five containers running. It was easy to manage. A year later, that five turned into fifty. I realized that half of my apps were running versions that were six months old, some of which had critical security vulnerabilities. I felt overwhelmed. When I discovered Watchtower, it felt like someone had handed me a personal assistant for my server. In this guide, I want to walk you through everything you need to know about this tool, from why it matters to how you can set it up without breaking your entire system.

What Exactly is Watchtower?

At its heart, Watchtower is an application that is also a Docker container. Its only job is to watch other containers. It monitors the Docker daemon for any changes in the images that those containers were originally started from. If Watchtower detects that a remote registry (like Docker Hub or GitHub Container Registry) has a newer version of an image than what you are currently running, it gets to work.

It pulls the new image down to your machine. Then, it gracefully shuts down the running container. Finally, it restarts the container using the exact same configuration you used originally (the same volumes, network settings, and environment variables) but with the brand new image. It is essentially an automated version of the “pull, stop, rm, run” workflow. The “containrrr” group maintains it now, and they have done a fantastic job keeping it lightweight and reliable.

Why Should You Use It?

The biggest reason is security. In the world of software, developers are constantly finding and fixing holes. When an official image gets an update, it often includes security patches for the underlying OS of that container. If you are not updating, you are leaving the door open for potential exploits. Watchtower ensures that as soon as a patch is released, your server adopts it.

Another reason is simply convenience. We all have better things to do than check for updates every morning. By automating this process, you ensure that you are always getting the latest features and performance improvements. However, I have to be honest here: automation comes with risks. I have had instances where a “latest” tag update broke my database because the developers changed the configuration format. I will talk about how to prevent that later, but the convenience usually outweighs the minor headaches.

Getting Started with the Setup

Setting up Watchtower is surprisingly simple. You do not need to install complicated binaries or configure databases. You can run it with a single Docker command. However, I always recommend using Docker Compose because it makes management much easier in the long run.

If you want to just try it out, you can run a command in your terminal. You tell Docker to run the containrrr/watchtower image and mount the Docker socket. The Docker socket is the “brain” of Docker on your host machine. By giving Watchtower access to it, you are giving it permission to see what else is running and to start or stop containers. Without that socket mount, Watchtower would be blind.

In a Docker Compose file, it looks something like this. You define a service called “watchtower.” You point it to the latest image from containrrr. You make sure to set the restart policy to “unless-stopped” so it stays running after a reboot. The most important part is the volume section where you map /var/run/docker.sock to the same path inside the container. Once you run docker-compose up -d, Watchtower is alive and checking your containers every 24 hours by default.

Understanding the Polling Interval

By default, Watchtower checks for updates every 86,400 seconds, which is exactly one day. For many people, this is fine. But if you are a bit more impatient or if you are running a development environment where images change frequently, you might want to change this.

You can use the WATCHTOWER_POLL_INTERVAL environment variable to set a custom time in seconds. Or, if you prefer a more “pro” approach, you can use a Cron schedule. Using a Cron expression allows you to say something like, “Check for updates every day at 3:00 AM when nobody is using the server.” This is a much cleaner way to handle things because it prevents your containers from restarting in the middle of a busy workday.

The Art of Filtering: Including and Excluding

One of the biggest mistakes beginners make is letting Watchtower update everything. This is dangerous. Imagine you are running a database like MariaDB or Postgres. Databases are sensitive. If Watchtower updates a database container and the new version requires a manual migration script, your database might fail to start, and you could lose data or experience significant downtime.

I learned this the hard way when my entire home automation system went dark while I was at work because a breaking change was introduced in a “latest” tag. Now, I use labels. You can tell Watchtower to only monitor containers that have a specific label. You do this by adding com.centurylinklabs.watchtower.enable=true to the labels section of the containers you actually want to auto-update. Then, you run Watchtower with the --label-enable flag.

Conversely, you can do the opposite. You can let Watchtower update everything except for a few specific “blacklisted” containers. This gives you granular control over your infrastructure. I personally prefer the “opt-in” method where I manually enable it for each service once I am confident that the service is stable enough to handle auto-updates.

Cleaning Up After Yourself

Every time Watchtower pulls a new image, the old image stays on your hard drive. Over time, these “dangling” images can take up gigabytes of space. I once found 50GB of old Nginx and Home Assistant images on a small SSD because I forgot to turn on cleanup.

To fix this, you should always use the WATCHTOWER_CLEANUP environment variable or the --cleanup flag. When this is enabled, Watchtower will delete the old image after the new one has successfully started. This keeps your server lean and prevents the dreaded “no space left on device” error that haunts many Docker users.

Private Registries and Authentication

If you are a developer or a business owner, you likely have images stored in private repositories. Out of the box, Watchtower cannot see these because it does not have your password. To solve this, you can mount your local config.json file (where Docker stores your login info) into the Watchtower container.

Alternatively, you can pass your username and password through environment variables like REPO_USER and REPO_PASS. This is essential if you are pulling from a private GitHub Container Registry or a Pro Docker Hub account. It ensures that Watchtower has the same permissions as your command-line interface.

Getting Notified When Things Happen

If a tree falls in a forest and no one is there to hear it, does it make a sound? If Watchtower updates a container and breaks it, but you don’t check the logs, you won’t know until hours later. This is why notifications are the most important part of a professional setup.

Watchtower supports a wide range of notification services through a library called Shoutrrr. You can get messages in Slack, Discord, Telegram, or even via email. I have mine hooked up to a Discord webhook. Every time Watchtower successfully updates a container, I get a nice little notification on my phone telling me which image was updated and what the new ID is. If an update fails, I get an alert, and I can jump on my computer to fix it immediately. This turns a “set it and forget it” tool into a proactive monitoring system.

Advanced Features: Lifecycle Hooks

For those who need even more control, Watchtower offers lifecycle hooks. These are scripts that run inside your container before or after an update. For example, if you have a complex application, you might want to run a backup script before the update happens. You can set a pre-check hook that tells your app to put itself into “maintenance mode” and then a post-check hook to bring it back online. This is the kind of feature that separates Watchtower from simpler update scripts.

Common Pitfalls and How to Avoid Them

The most common issue I see is people using the “latest” tag for everything. While Watchtower is designed for this, “latest” is a bit of a gamble. Some developers use it for stable releases, while others use it for their most recent (and potentially broken) builds. My advice is to use specific version tags where possible or only use “latest” for applications with very high stability standards.

Another issue is network dependencies. If you update a container that provides DNS for your other containers (like Pi-hole or AdGuard Home), and Watchtower takes it offline for a few seconds to update it, your other containers might lose connectivity during that window. Always plan the order of your updates or use the scheduling feature to do these during low-traffic periods.

My Personal Take on Watchtower

In my years of managing servers, Watchtower has become a non-negotiable part of my stack. However, my philosophy has shifted. I no longer auto-update my core infrastructure (firewalls, databases, or main websites). I prefer to update those manually after reading the changelogs. But for the dozens of supporting apps like dashboard tools, weather scrapers, and utility containers, Watchtower is a godsend.

It reduces my mental load significantly. Instead of worrying about 40 different apps, I only worry about the big three or four. The rest just stay fresh and secure on their own. It is about finding the right balance between automation and manual oversight.

Conclusion

Containrrr Watchtower is a must-have for anyone serious about using Docker. It bridges the gap between a static, outdated server and a dynamic, secure environment. By understanding how to use polling intervals, labels for filtering, and notification systems, you can build a self-healing infrastructure that requires very little maintenance.

Just remember to treat your databases with care and always keep the cleanup flag turned on. If you do that, you will find that your Docker experience becomes much smoother and far more professional. Whether you are running a single Raspberry Pi at home or a cluster of servers in the cloud, Watchtower is the silent partner that keeps everything running behind the scenes.

FAQ (Frequently Asked Questions)

1. Does Watchtower work with Docker Swarm?
Watchtower is primarily designed for standalone Docker engines. While there are ways to make it work in a Swarm environment, most Swarm users prefer using built-in service update mechanics.

2. Will I lose my data when Watchtower restarts a container?
No, as long as you have mapped your data to persistent volumes. Watchtower restarts the container with the exact same arguments, including volume mounts. If you are not using volumes and storing data inside the container itself, you will lose it (but you should never store data that way anyway).

3. Can Watchtower update itself?
Yes! If you are running Watchtower as a container, it can monitor its own image and update itself just like any other container.

4. How do I stop Watchtower from updating a specific container?
The easiest way is to use the label com.centurylinklabs.watchtower.enable=false on that specific container and then run Watchtower with the --label-enable flag to only target containers you have specifically tagged.

5. Is Watchtower heavy on system resources?
Not at all. It is written in Go and is very lightweight. Most of the time, it just sits idle and waits for the next polling interval.

Leave a Reply

Your email address will not be published. Required fields are marked *