Update Docker images with Watchtower

June 30th 2023 Docker GitHub Synology

After I set up a self-hosted GitHub Actions runner on my Synology NAS, it only worked without issues until a new version of the image had been released. Since I couldn't get automatic updates working with my setup, I settled with a manual update process for the time being. When a reader suggested that I could use Watchtower instead, I decided to try it out when the next version of the runner is released.

Because I was already using Docker Compose for the GitHub Actions runner, I wanted to add Watchtower to the same docker-compose.yml file to keep everything in one place. I also wanted Watchtower to only update the GitHub Actions runner image and not to interfere with any other containers that might be running in the same Docker instance.

Fortunately, I could find an example in the documentation that fully met these requirements. I didn't need to change much in my existing docker-compose.yml file to add Watchtower to it:

  • I added a Watchtower service to it.
  • I set a com.centurylinklabs.watchtower.scope label for the GitHub Actions runner service and then passed its value as scope argument in Watchtower's command to limit which containers it should monitor and update.
  • I disabled the auto update feature for the GitHub Actions runner. It didn't work as expected anyway, but I kept it enabled before to stop the runner when the update failed and in doing that notify me when a manual update was necessary.

This was the resulting docker-compose.yml file:

version: "2.3"

    image: myoung34/github-runner:latest
      ORG_NAME: yourOrgName
      ACCESS_TOKEN: someGithubTokenHere
      RUNNER_WORKDIR: /tmp/github-runner
      RUNNER_SCOPE: "org"
      - "/volume1/docker/docker.sock:/var/run/docker.sock"
      - "/volume1/docker/github-runner:/volume1/docker/github-runner"
      # note: a quirk of docker-in-docker is that this path
      # needs to be the same path on host and inside the container,
      # docker mgmt cmds run outside of docker but expect the paths from within
      - "com.centurylinklabs.watchtower.scope=github-runner"

    image: containrrr/watchtower:latest
      - "/volume1/docker/docker.sock:/var/run/docker.sock"
    command: --scope github-runner
      - "com.centurylinklabs.watchtower.scope=github-runner"

By default, Watchtower checks for new versions of images every 24 hours, which is fine for regular use. I didn't want to wait that long to see if my configuration worked as expected, so I temporarily changed the polling interval by adding the --interval 30 argument to the Watchtower command in the docker-compose.yml file above. Once I was done with testing, I removed that argument again.

I'm glad to have learned about Watchtower. It's easy to configure and a great fit for my issue with updating the GitHub Actions runner. I'm certain I'll find use for it in other scenarios in the future.

Get notified when a new blog post is published (usually every Friday):

If you're looking for online one-on-one mentorship on a related topic, you can find me on Codementor.
If you need a team of experienced software engineers to help you with a project, contact us at Razum.
Creative Commons License