Updating your containers with Diun and Watchtower

Containers Oct 7, 2021

So you've fallen in love with docker and gone a little container crazy. You're self-hosting everything you can and then some, and you've got databases for your databases. Or you've just got Plex and you're doing fine.  

Either way, you know that these containers will at some point be updated by their developers, providing upgrades, bug fixes, new features, the list goes on. But you're busy, and you can't spare the time to continually check for these new updates.

Enter the Diun and Watchtower containers. I use them both, and I'll explain why over the course of this article. I'll show you how to set them up with a notification tool called Pushover.


Diun

This is a pure notification tool, and works best when you use docker-compose to create your containers. By using labels in the compose files of the containers you want to monitor, you can set it to track newly pushed images across multiple release tags, or only a few, or only one. It will then notify you, and has a variety of notification methods you can use. As mentioned above, I'll be showing you how to set it up with Pushover.

Before we create the container, we're going to do a few things to prep:

Creating your pushover account, apptoken and userkey

Head over to the pushover website and log in or create a free account.

Once logged in, you'll see a screen similar to this:

ctrl+click to enlarge
  • Copy the 'User Key' you see in the top right quadrant of the screen and save it for later
  • Scroll down until you see 'Your Applications (Create an Application/API Token)'
ctrl+click to enlarge
  • Click 'Create an Application/API Token' which will take you to the next screen:
ctrl+click to enlarge
  • Enter a name, add a description and icon if you like, check the check box, and hit Create Application. Your pushover app will be created, and the next screen will show you your API key:
ctrl+click to enlarge
  • Copy this API Key and make sure you remember the difference between this one and the User Key. You'll need them when we come to create the container
  • Final step is to download pushover to your mobile device, or register your browser (all available from your user area on the pushover site) to receive your notifications

Creating the Diun container

Initial steps:

  • In your docker directory, create a new folder called diun, and inside that folder create another called data
  • Create a new docker network called diun by logging into your server via SSH and typing:
sudo docker network create diun
make sure your firewall isn't blocking the new docker bridge network
  • Inside your diun folder, create a file called docker-compose.yml and paste the following:
services:  
  diun:
    image: crazymax/diun:latest
    container_name: diun
    volumes:
      - "your/folder/path/to/diun/data:/data" #change as necessary
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment:
      - "LOG_LEVEL=info"
      - "LOG_JSON=false"
      - "DIUN_WATCH_WORKERS=20"
      - "DIUN_WATCH_SCHEDULE=0 */6 * * *" #change as necessary
      - "DIUN_PROVIDERS_DOCKER=true"
      - "DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=false"
      - "DIUN_NOTIF_PUSHOVER_TOKEN=#enter your pushover API Key" 
      - "DIUN_NOTIF_PUSHOVER_RECIPIENT=#enter your pushover User Key"
    restart: unless-stopped
    labels:
      - "diun.enable=true"
      - "diun.watch_repo=true"
      - "diun.include_tags=latest"    

networks:
  default:
    name: diun
    external: true
  • Change the folder path to point to diun/data which you set up a few steps back
  • Insert your API Key for the Diun app you created in Pushover earlier
  • Insert your Pushover User Key

Let's break down a few lines of the above compose file:

  • LOG_JSON=false means we won't output the logs to a json file. Your call if you want to change this to true
  • DIUN_WATCH_SCHEDULE=0 */6 * * * will tell Diun to check images every 6 hours. You can change this to your preferred frequency
  • DIUN_PROVIDERS_DOCKER=true informs Diun how it will know which images to check. We're telling it that it will come via docker containers
  • DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=false means that I don't want Diun to just watch images for every container it has access to. Because I have Watchtower monitoring some images, it makes no sense to also have Diun monitoring them

Spin up your container by logging into your machine via SSH, navigating to your diun folder and typing docker-compose up -d.

This has Diun running, but how does it know which container images to follow? Well, we need to add labels to those containers:

    labels:
      - "diun.enable=true"
      - "diun.watch_repo=true"
      - "diun.include_tags=latest"

For instance, you could add it directly to your Diun docker-compose file:

services:  
  diun:
    image: crazymax/diun:latest
    container_name: diun
    volumes:
      - "your/folder/path/to/diun/data:/data" #change as necessary
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment:
      - "LOG_LEVEL=info"
      - "LOG_JSON=false"
      - "DIUN_WATCH_WORKERS=20"
      - "DIUN_WATCH_SCHEDULE=0 */6 * * *" #change as necessary
      - "DIUN_PROVIDERS_DOCKER=true"
      - "DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=false"
      - "DIUN_NOTIF_PUSHOVER_TOKEN=#enter your pushover API Key" 
      - "DIUN_NOTIF_PUSHOVER_RECIPIENT=#enter your pushover User Key"
    restart: unless-stopped
    labels:
      - "diun.enable=true"
      - "diun.watch_repo=true"
      - "diun.include_tags=latest"    

networks:
  default:
    name: diun
    external: true

Notice the labels block. The first two lines are the minimum that Diun needs to monitor the repository for new image pushes, in this case telling it to watch the crazymax/diun repo (notice the line image: crazymax/diun:latest). Initially I started off with only those two lines, however found that because a new version gets a new push for each OS/different architecture type, Diun was picking up all of them. That was no good.

The next line tells Diun to only follow the 'latest' tag for this particular image.

Copy these labels into all the docker-compose files for the services you want Diun to monitor.


Updating containers manually

Diun tells you when a new image is available, but doesn't actually update your container for you.

This is actually really easy, but you need to be able to SSH into your machine.

  • Log in via SSH
  • Type sudo docker pull [image:tag] and press Enter

So if you wanted to pull the crazymax/diun:latest image,  you would type

sudo docker pull crazymax/diun:latest
you could also just pull the crazymax/diun image, when no tag is specified then the latest is pulled by default

If no new image was available, it will tell you you have the latest release, or it will go through and download the new image from the repo. You will then be able to do another docker-compose up -d from the directory which holds your compose file, and the container will use the updated image.


Watchtower

This container has an option to be like Diun, i.e. monitor and notify only. However that's not why I use it. I use it to monitor and update my containers automatically.

it should be noted that I only use this function on those containers I don't mind breaking through a bad update, which I'll then have to go back and fix, or roll-back to a previous release

Watchtower can also notify you when it's done this. You can use email, pushbullet, discord.... again I'll show you with Pushover.

Configure your Watchtower app in Pushover

  • Head back to your Pushover account and create a new app called Watchtower (or whatever you want to call it)
  • Note down the new API Key (we'll be using the same User Key as for Diun, that doesn't change)
  • Note down your device name which you created when you registered your browser or logged in via your mobile device:

Creating your Watchtower container

We'll need similar prep as before:

  • Create your watchtower network via SSH
sudo docker network create watchtower
  • Create a watchtower folder in your docker directory
  • Create a docker-compose.yml file inside your watchtower folder
  • Copy paste the following into the docker-compose.yml file:
services:  
  watchtower: #automatic container version monitoring and updating
    container_name: watchtower
    image: containrrr/watchtower:latest
    environment: 
      - DEBUG=true
      - WATCHTOWER_LABEL_ENABLE=true
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_INCLUDE_RESTARTING=true
      - WATCHTOWER_INCLUDE_STOPPED=true
      - WATCHTOWER_NOTIFICATIONS=shoutrrr
      - WATCHTOWER_NOTIFICATION_URL=pushover://shoutrrr:[API Key]@[User Key]/?devices=[enter device name]
    command: --interval 21600
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - "diun.enable=true"
      - "diun.watch_repo=true"
      - "diun.include_tags=latest"
networks:
  default:
    name: watchtower
    external: true
make sure you add your api key, user key and device name in the correct line above, and remove the [ ] brackets

Let's break this down again:

  • WATCHTOWER_LABEL_ENABLE=true tells Watchtower that, like Diun, it will be sent information via labels in other containers' compose files
  • WATCHTOWER_CLEANUP=true means that it will automatically remove old images which are no longer in use
  • WATCHTOWER_INCLUDE_RESTARTING/STOPPED=true means that it will restart the containers once the image has been updated, and it will include any containers which are stopped (they remain stopped)
  • shoutrrr is the notification agent for Watchtower, and the NOTIFICATION_URL is the string for using Pushover
  • command: --interval 21600 is the time in seconds between checks. This is 6 hours, change this to your preferred frequency
  • labels: are our diun labels! I don't really want watchtower trying to restart itself - I don't even know if it can - so I have Diun monitor the repo for any new images

Spin up your container by typing docker-compose up -d after logging in via SSH and navigating to your /docker/watchtower folder.

Again, we need to add labels to the containers we want watchtower to follow:

com.centurylinklabs.watchtower.enable=true
worth noting, these other containers don't have to be on the same bridge or docker network as watchtower. That's helpful!

I use a service uptime monitoring tool called Uptime-Kuma, and I have it updated automatically via Watchtower. It's compose file looks like this:

services:  
  uptime-kuma:
    image: louislam/uptime-kuma
    container_name: uptime-kuma
    volumes:
      - $DOCKERDIR/kuma:/app/data
    ports:
      - 3001:3001
    labels:
      - com.centurylinklabs.watchtower.enable=true

Rinse and repeat.


Related Article

Portainer - Easy Container Management for Docker
A step-by-step docker walkthrough to installing and configuring Portainer, your one-stop container-management resource

PTS

PTS fell down the selfhosted rabbit hole after buying his first NAS in October 2020, only intending to use it as a Plex server. Find him on the Synology discord channel https://discord.gg/vgSq5pcT

Have some feedback or something to add? Comments are welcome!

Please note comments should be respectful, and may be moderated