Watchtower – Automatic Docker Container Updater

With Watchtower, you can automatically update the image of your deployed containers. It will, based on your schedule, pull the images you have associated with all running containers on your server. Then if it sees a difference in version, gracefully shut down your existing container and restart it with the same options.

In the past, I have always had the mindset of “I’ll do all my own container management so I can maintain versions and make sure nothing automatically upgrades and breaks my systems”. The more systems I build out and the more complex the systems get, I realized this is a bigger undertaking then I originally thought. I still keep the mindset of hard setting my container image versions in my stacks, however even the version images sometimes get updates to fix issues. To maintain that would be daunting to say the least.

Because of this, I started deploying Watchtower on all my Docker servers. This gives me flexibility to just update images based on a new push to Docker Hub for the security and simple updates of the version images, or I can set the tag to “latest” for some containers I don’t need to worry about breaking with upgrades and it will always be up to date. It also gives me the ability to exclude automatic updates for containers by utilizing Labels, which I will cover in this walkthrough.


Prerequisites

I will be setting this up on Portainer utilizing Docker Containers running on Ubuntu 24.04. Here are my setup guides for all of those pieces of software:


Deployment

---
services:
  watchtower:
    image: containrrr/watchtower:latest
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      TZ: America/Los_Angeles
      WATCHTOWER_CLEANUP: true
      WATCHTOWER_REMOVE_VOLUMES: false
      DOCKER_API_VERSION: 1.45
      WATCHTOWER_INCLUDE_RESTARTING: true
      WATCHTOWER_INCLUDE_STOPPED: false
      WATCHTOWER_SCHEDULE: "0 0 */2 * * *"
      WATCHTOWER_LABEL_ENABLE: false
      WATCHTOWER_ROLLING_RESTART: true
      WATCHTOWER_TIMEOUT: 30s
      WATCHTOWER_LOG_FORMAT: pretty
    restart: always

Stuff to change for your deployment:

  • Image – Since this is a supporting container and nothing is dependent on it working, I just keep this on “latest”. If you want to specify a version, you can, it just adds more maintained which this container is supposed to fix. Here is a link to the Watchtower Tag page.
  • TZ – Update this to be your Time Zone. Here is a link to a list of all Time Zones.
  • Cleanup – If you set this to “true”, Watchtower will automatically clean up the old unused images from the system for you.
  • Remove Volumes – If you set this to “true”, Watchtower will automatically remove all anonymous volumes from the container before restarting with the new image. Named volumes will not be removed.
  • Docker API Version – This you will want to set the version of your Docker API you are running on your system. Minimum version is 1.24. You can find your version by going to the console of your server and running “docker version” command.
  • Include Restarting – If you set this to “true”, Watchtower will also update restarting containers.
  • Include Stopped – If you set this to “true”, Watchtower will also update created and exited containers.
  • Schedule – You can set to whatever time variation you want utilizing Crontab. If you use my entry, it will check on the hour mark, every 2 hours, every day. Here is a link to a Crontab generator you can use to generate your own schedule.
  • Label Enable – If you set this to “true”, Watchtower will only update containers that have the watchtower label set in their config. I will cover how to do this later in the walkthrough.
  • Rolling Restart – If you set this to “true”, Watchtower will only restart one container at a time instead of restarting all containers that have updates all at the same time. Pair this with the Lifecycle hooks to add dependency to certain containers and you can automatically update complex systems without any downtime or conflicts.
  • Timeout – You can set this preference for how long the system should wait to forcefully stop a container. The default is 10 seconds, I set mine to 30 just to give it a little more time to come back online.
  • Log Format – You can set this to how you want the logs to look. The options are Auto, LogFmt, Pretty or JSON. I use Pretty since I check the log files directly on the container.
  • Restart – You will want to set this to the way you want docker to handle the restarting of the container. Here is a link to the Restart Policies to choose from. I prefer “always” so if it crashes or the server restarts, it will automatically restart the container.

These are all the arguments I use in my stack however there are a lot more available to this system. Here is a link to the official Watchtower Arguments page.


First deploy and Update Process

After you deploy the stack, we need to check the logs to see what Watchtower is doing. There isn’t a native interface for this container but the logs give you enough information.

Check this by going to the “Logs” in Portainer under the container:

Or by using the “docker logs watchtower” command in the console of the server.

When you first start up Watchtower, you will see the version, your notifications (if you have them setup, will go over that later), and the next time the schedule will run.

After the schedule time arrives, it will check all images that match the requirements and download any new images available. Once it has finished checking all the containers, it will start the restart process for each container.

Once it is finished, it will say “Session done” and give you a summery of what it did.

The container will continue to run and each time the schedule time happens, it will do it’s check and update any new images.

Make sure if you don’t enable the cleanup flag, you need to manually clean up the old images.

Labels

If you want to filter which containers get automatically updated, Labels will do it for you.

You will need to add the Label Environment Variable to your Watchtower compose file/stack. Here is the line to add:

WATCHTOWER_LABEL_ENABLE: true

Next, you will need to add a label to the container you want to update. Here is the lines you need to add to the compose file/stack:

labels:
   - "com.centurylinklabs.watchtower.enable"

Notifications

I don’t use notifications since all systems I have auto update aren’t critical functions so I’m not worried about knowing exactly when they update.

If you want to receive notifications to know when your systems update, there is a whole page on their dev site documenting all the options. I might utilize notifications in the future if my process isn’t working and I want to change it again, if I do, I’ll update this article with the settings I use.


I have been using Watchtower for about a month now and it has really been nice to not have to worry that I’m exposing an outdated container or not on the current version.

Hopefully this helped you deploy it to your systems. If it did help or you have different setting, comment below so we can all collaborate together.

Related Posts

Nginx Proxy Manager – Reverse Proxy

I have been using Nginx Proxy Manager for a few years now. Not sure why it took me this long to write an article about it but…

Trilium Notes – Hierarchical Note Taking Application

In my quest to replace all of the Google Services with self hosted applications, I have been looking for a note taking application to replace Google Keep…

Lidify – Discover Artist based on your Library

If you followed my Lidarr setup and deployed that container, you might notice that there isn’t a “Discovery” feature for new artists like there is with Radarr…

Lidarr – Music Management Server

Lidarr is a music collection manager for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new albums from your favorite artists and will interface…

Pinchflat – Channel Monitoring YouTube Downloader

Pinchflat is a self-hosted app for downloading YouTube content built using yt-dlp. It’s designed to be lightweight, self-contained, and easy to use. You set up rules for…

SearXNG – Internet Metasearch Engine

SearXNG is a free internet metasearch engine which aggregates results from more than 70 search services. Here is the Wikipedia page on how metasearch engines work. With…

Leave a Reply

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