How to automatically update your docker containers, if base-images are updated
Say I have a trivial container based on the ubuntu:latest
. Now there is a security update and ubuntu:latest
is updated in the docker repo .
How would I know my local image and its containers are running behind?
Is there some best practice for automatically updating local images and containers to follow the docker repo updates, which in practice would give you the same niceties of having unattended-upgrades running on a conventional ubuntu-machine
We use a script which checks if a running container is started with the latest image. We also use upstart init scripts for starting the docker image.
#!/usr/bin/env bash
set -e
BASE_IMAGE="registry"
REGISTRY="registry.hub.docker.com"
IMAGE="$REGISTRY/$BASE_IMAGE"
CID=$(docker ps | grep $IMAGE | awk '{print $1}')
docker pull $IMAGE
for im in $CID
do
LATEST=`docker inspect --format "{{.Id}}" $IMAGE`
RUNNING=`docker inspect --format "{{.Image}}" $im`
NAME=`docker inspect --format '{{.Name}}' $im | sed "s/\///g"`
echo "Latest:" $LATEST
echo "Running:" $RUNNING
if [ "$RUNNING" != "$LATEST" ];then
echo "upgrading $NAME"
stop docker-$NAME
docker rm -f $NAME
start docker-$NAME
else
echo "$NAME up to date"
fi
done
And init looks like
docker run -t -i --name $NAME $im /bin/bash
A 'docker way' would be to use docker hub automated builds. The Repository Links feature will rebuild your container when an upstream container is rebuilt, and the Webhooks feature will send you a notification.
It looks like the webhooks are limited to HTTP POST calls. You'd need to set up a service to catch them, or maybe use one of the POST to email services out there.
I haven't looked into it, but the new Docker Universal Control Plane might have a feature for detecting updated containers and re-deploying.
You can use Watchtower to watch for updates to the image a container is instantiated from and automatically pull the update and restart the container using the updated image. However, that doesn't solve the problem of rebuilding your own custom images when there's a change to the upstream image it's based on. You could view this as a two-part problem: (1) knowing when an upstream image has been updated, and (2) doing the actual image rebuild. (1) can be solved fairly easily, but (2) depends a lot on your local build environment/practices, so it's probably much harder to create a generalized solution for that.
If you're able to use Docker Hub's automated builds, the whole problem can be solved relatively cleanly using the repository links feature, which lets you trigger a rebuild automatically when a linked repository (probably an upstream one) is updated. You can also configure a webhook to notify you when an automated build occurs. If you want an email or SMS notification, you could connect the webhook to IFTTT Maker. I found the IFTTT user interface to be kind of confusing, but you would configure the Docker webhook to post to https://maker.ifttt.com/trigger/`docker_xyz_image_built`/with/key/`your_key`.
If you need to build locally, you can at least solve the problem of getting notifications when an upstream image is updated by creating a dummy repo in Docker Hub linked to your repo(s) of interest. The sole purpose of the dummy repo would be to trigger a webhook when it gets rebuilt (which implies one of its linked repos was updated). If you're able to receive this webhook, you could even use that to trigger a rebuild on your side.
One of the ways to do it is to drive this through your CI/CD systems. Once your parent image is built, have something that scans your git repos for images using that parent. If found, you'd then send a pull request to bump to new versions of the image. The pull request, if all tests pass, would be merged and you'd have a new child image based on updated parent. An example of a tool that takes this approach can be found here: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 .
If you don't control your parent image, as would be the case if you are depending on the official ubuntu
image, you can write some tooling that detects changes in the parent image tag or checksum(not the same thing, tags are mutable) and invoke children image builds accordingly.