Update local docker images and replace running containers with ease. Define images to watch and trigger commands whenever they get updated.

Docker containers can make deploying and running services easier, but it also introduces additional complexity. docker push and docker pull provide simple ways to push new images to a central image repository and to then pull those images down to your docker hosts, but this doesn’t solve the issue of when to pull, or what.

To solve this problem one could build a pipeline where the Docker Hub Registery or your own custom build server triggers a deployment process to update the correct image(s) on the correct Docker hosts and then restart affected containers, but depending on your architecture this may be a non-trivial thing to set-up.

Implementing such a system will likely introduce many moving parts, introducing various points of potential failure. What if your webserver is having a hickup and a webhook fails to be delivered? What if a certain Docker host is down and doesn’t receive the command to update a certain image or container? You might go on running an old version of your image unless you add additional tooling and safety checks to deal with these types of situations.

I struggled with this situation myself and couldn’t find anything out there to solve this problem in a simple way, so I built docker-image-updater for this.

The idea is simple; Instead of reacting to incoming notifications, we periodically check for updated images on the docker hosts themselves by pulling images we have defined. If a newer version of an image gets pulled down then we execute some predefined command(s).

It takes a simple YAML configuration, which is both easy to read for humans and simple to parse and manage in scripts. I use Ansible for orchestration and have a custom module to add/remove sections to /etc/docker-image-updater.yml programmatically in the same playbooks that define which containers run on which hosts.

# /etc/docker-image-updater.yml

config:
  docker:
    base_url: "unix://var/run/docker.sock"
    version: "1.16"
watch:
  my-app:
    images:
     - my-app
     - redis
    commands:
     - restart my-app

Configure cron to run docker-image-updater periodically (using something like cronic to keep cron spam at bay) and you have a simple system in place to keep your docker containers up to date, with very few moving parts.