Part 11 — How I Run My Entire Digital Life on a Raspberry Pi: Keep Your Containers Fresh with Watchtower

Part 11 — How I Run My Entire Digital Life on a Raspberry Pi: Keep Your Containers Fresh with Watchtower

Table of Contents

Updated: 08/2026

Keeping your Docker containers up to date is crucial for security, reliability, and making sure you benefit from the latest improvements — but manually updating containers can be tedious and easy to forget. That’s where Watchtower comes in! Watchtower automatically monitors your running containers and updates them in the background whenever new images are available. Even better, you can integrate Watchtower with Gotify to receive instant notifications whenever an update occurs. In this section, we’ll show you how to automate container updates with Watchtower and stay informed in real time with Gotify, making Docker maintenance effortless and keeping your stack secure and current.

Image generated by chatGPT then some final touches were made manually with Gimp Image generated by chatGPT then some final touches were made manually with Gimp

Watchtower

Watchtower is a lightweight, open-source tool designed to automate the process of keeping your Docker containers up to date. It runs as its own Docker container and continuously monitors your running containers for updates to their underlying images. When a new version of an image becomes available — whether from Docker Hub or a private registry — Watchtower automatically pulls the latest image, gracefully stops the old container, and restarts it with the updated image

How Watchtower Works:

  • Watchtower interacts with the Docker API by mounting the Docker socket (/var/run/docker.sock), giving it the necessary access to monitor and manage other containers.
  • It periodically checks for updates to the images used by your running containers. By default, this check happens every 24 hours, but you can customize the interval or schedule with environment variables like WATCHTOWER_POLL_INTERVAL.
  • When an updated image is detected, Watchtower pulls the new version, stops the running container, and starts a new container instance with the latest image — preserving your configuration and minimizing downtime.
  • You can configure Watchtower to watch all containers or only specific ones, and it supports both public and private registries.
  • Installation is simple: just run the Watchtower container with the appropriate volume mounts, and it will handle the rest.

In essence, Watchtower turns container maintenance into a hands-off process, ensuring your applications always run the latest and most secure versions without manual intervention.

Deploy our new stack

Let’s navigate once again to our Portainer, and create a new stack. Name it as watchtower, and adapt the following docker-compose.yml:

services:
  watchtower:
    container_name: watchtower
    hostname: watchtower
    restart: unless-stopped
    image: nickfedor/watchtower:latest
    environment:
      #### DEPRICATED
      # - WATCHTOWER_NOTIFICATIONS=gotify 
      # - WATCHTOWER_NOTIFICATION_GOTIFY_URL=http://172.30.1.15
      # - WATCHTOWER_NOTIFICATION_GOTIFY_TOKEN=[YOUR_GOTIFY_APP_TOKEN]
      - WATCHTOWER_NOTIFICATION_URL=gotify://172.30.1.15/[YOUR_GOTIFY_APP_TOKEN]?disabletls=yes
      - WATCHTOWER_SCHEDULE=0 0 4 * * *
      - WATCHTOWER_CLEANUP=true      
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '/etc/localtime:/etc/localtime:ro'
      - '/etc/timezone:/etc/timezone:ro'
    dns: 172.30.1.3
    networks:
      - pi_docker_network

networks:
  pi_docker_network:
    external: true

As you can see, the docker-compose setup is straightforward. There are a few environment variables to configure for notifications and general operation. To enable Gotify notifications, create a new application in Gotify and use its token. With just these three Gotify-related environment variables, Watchtower handles the rest. The WATCHTOWER_SCHEDULE variable uses the familiar crontab syntax—in this example, it’s set to check for updates every day at 4 a.m. and pull new images if available. Setting WATCHTOWER_CLEANUP=true ensures that Watchtower automatically deletes old Docker images after updating containers, preventing unused images from taking up disk space.

A quick note on that image tag before you deploy: containrrr/watchtower — the image every Watchtower tutorial on the internet, including an earlier version of this very post, tells you to pull — was archived on GitHub in December 2025 after sitting untouched for years. nicholas-fedor/watchtower (shipped on Docker Hub as nickfedor/watchtower) picked up right where it left off — same labels, same environment variables, zero migration pain. That’s the fork already sitting in the compose above.

Here’s the gotcha that actually got me, and it was hiding in plain sight in that same compose file: don’t hardcode a static ipv4_address on Watchtower’s own network attachment. Watchtower can’t cleanly swap itself out the way it swaps out every other container — the process doing the replacing is the process being replaced — so by default it renames the running instance instead of removing it outright, and only cleans that renamed leftover up on the next startup. Updating itself while running is a bit like changing a tire while the car’s still rolling: something has to stay parked long enough to finish the job, and that something is a stale, renamed container still squatting on the one IP address you told it to keep forever. The replacement container gets created, reaches for that same address, finds it taken, and never starts. What you actually see: a phantom watchtower container stuck in Created state every morning after the 4 a.m. schedule fires, quietly not watching anything until you notice and restart it by hand.

The fix is the line already missing from the compose above — don’t pin the IP, just list the network by name and let Docker hand out whatever’s free. Nothing calls into Watchtower over the network, so a fixed address was never buying you anything.

One more thing the block above already dodges that the originally published version doesn’t: a Using deprecated legacy gotify notification configuration. Use the notification-url configuration option instead. warning in the logs on first boot. Watchtower’s consolidating every notification integration onto Shoutrrr, a single unified notification library, and the old three-variable-per-service setup gets removed outright whenever Watchtower ships v2. It’s a warning today, not a failure — but the fix is one line, so there’s no reason to wait for the deadline. The part worth calling out explicitly: that disabletls=yes on the end isn’t decoration. Shoutrrr’s Gotify integration assumes HTTPS by default, and this setup runs Gotify over plain HTTP as it sits besides it in the same container network. Drop that parameter and you don’t get a warning next time — you get silence, with nothing in the logs telling you why.

Let’s go ahead and deploy, then check the logs. If everything is working correctly, the logs should look normal without any unusual messages. Additionally, you’ll receive a startup notification from Watchtower in your Gotify app.

Real-time watchtower notifications on our Gotify server Real-time watchtower notifications on our Gotify server

Disable auto-update

While I’m a big fan of Watchtower, there are times when you might want to prevent certain containers from being updated automatically. For example, I’ve had situations where a new Home Assistant release broke some plugins, required extra in-app updates, or deprecated tools I rely on. To avoid unwanted updates like these, you can exclude specific containers by adding a label in their docker-compose configuration. Watchtower will recognize this label and skip updating those containers.

Just add the following lines to the container you want to exclude:

labels: #to disable watchtower to update the image
  - com.centurylinklabs.watchtower.enable="false"

Or, you can specify the same within the watchtower docker stack instead. In fact, the trick of not updating watchtower can be applied by adding this extra environment variable to watchtower’s compose stack:

environment:
  - WATCHTOWER_DISABLE_CONTAINERS=watchtower

And, as you can see, the disabling is based on the containers name. So, if you don’t want to update homeassistant, just append it to the line, separated by comma (,).

In summary, Watchtower is a powerful and convenient tool for automating Docker container updates, ensuring your services stay current with minimal effort. By integrating it with Gotify, you can receive real-time notifications whenever updates occur, keeping you informed and in control. With customizable scheduling, automatic cleanup of old images, and the ability to exclude specific containers from updates, Watchtower offers both flexibility and peace of mind. Setting it up is straightforward, and once deployed, it takes the hassle out of container maintenance, letting you focus on what matters most while your stack stays secure and up to date.