Update your Docker containers safely

Safe Harbor

Automating Update Checks

When I first pulled down an Nginx image as nginx:alpine in Listing 1, it turned out to be version 1.13. Using safe version logic, I should change the nginx:alpine tag in the YAML file to nginx:1.15-alpine.

Now I can update manually by running:

docker-compose pull
docker-compose up -d

Alternatively, you can let an automated solution update your containers. Watchtower [1] (a Docker container), can do this for you, although I have not tested it.

However, I want to stick with manual updating, and I simply want to know when updates are available for <image><tag> (compared with my current image, of course). If an update is available, I can make a snapshot of the virtual machine on which Docker runs, update, and roll back if things go wrong. This time, I use a script and learn something about image IDs, as well.

First, you need two more pieces of information: what version and image ID are you running and how it compares with the latest container ID of the version to which you want to update. The first item was already solved above, but not the second.

Repo ID vs. Image ID

The image ID was discovered by analyzing the manifest file of an image and extracting the version of the software. However, for an automated solution, this process won't do because every software project uses versions in a slightly different way. Therefore, you need a more general ID.

A Docker manifest uses several IDs, two of which are the image ID, which is a hash of the uncompressed image, and the repo ID (repo digest), which is a hash of the compressed image when it sits in the registry (from which you pull your images). Both are digests, by the way, but with different data payload forms.

Confusingly, different Docker command-line options show both IDs or parts of both, as you can see in the confusing output of the docker images command in Listing 5, which shows information about images you pulled to your computer.

Listing 5

docker images Output

docker images --digests
REPOSITORY   TAG           DIGEST                                                                    IMAGE ID       CREATED         SIZE
nginx        1.15-alpine   sha256:385fbcf0f04621981df6c6f1abd896101eb61a439746ee2921b26abc78f45571   315798907716   5 days ago      17.8MB
nginx        alpine        sha256:f1ca87d9adb678b180c31bf21eb9798b043c22571f419ed844bca1d103f2a2f7   bf85f2b6bf52   13 months ago   15.5MB

The output shows information on both the original nginx:alpine image and the updated nginx:1.15-alpine. The Image ID column refers to a short version of the (local unpacked) image ID and the Digest column refers to the repo ID.

If you want to see both the full image hash and the repo digest of an image on a Docker host, the command in Listing 6 shows both.

Listing 6

docker image inspect

01 docker image inspect 315798907716 | head
02     {
03         "Id": "sha256:315798907716a51610bb3c270c191e0e61112b19aae9a3bb0c2a60c53d074750",
04         "RepoTags": [
05             "nginx:1.15-alpine"
06         ],
07         "RepoDigests": [
08             "nginx@sha256:385fbcf0f04621981df6c6f1abd896101eb61a439746ee2921b26abc78f45571"

The "Id" (line 3) shows the image ID: The first 12 characters are the same as the output from docker images; the repo ID is the repo digest. By the way, docker image inspect reads a downloaded image manifest file that you get when you pull an image.

For the automated update check, you will collect both the image and repo IDs, but only the image ID can be used to automate a check without pulling an image because of the Docker Registry API (as far as I know).

A Scripted Update Check

After searching and finding some Bash scripts on GitHub that work on the Docker Registry API, I have come up with this solution:

1. A local Docker script first produces a local file on a Docker host with per-line <image><tag><current image ID> and a second line with <image><tag><current repo ID>. You can run this script on many Docker hosts, combine lines, and use one central host to check for updates on many Docker images you might have in production.

2. A second script reads the local file and, for each line, checks Docker Hub for the <image ID> of the latest version of <image><tag>; compares the local image tag to the image ID of latest on the Hub; and lets you know what local Docker services thus can be updated (if local and remote IDs don't match).

Although you can probably find many ways to solve this problem, the script lets you check a number of different images at the same time. Also, a centralized check is possible by combining with a centralized scanning solution.

The scripts to do this can be found on GitHub [2], which you can either clone or download one by one (Listing 7), because Git is quite a large package [3].

Listing 7

Downloading Update Scripts

mkdir dockerscripts
cd dockerscripts
curl https://raw.githubusercontent.com/hanscees/dockerscripts/master/scripts/check-docker-image-updates.sh > check-docker-image-updates.sh
 curl https://raw.githubusercontent.com/hanscees/dockerscripts/master/scripts/get-docker-hub--image-tags.sh > get-docker-hub--image-tags.sh
 curl https://raw.githubusercontent.com/hanscees/dockerscripts/master/scripts/get-docker-hub-image-tag-digest.sh > get-docker-hub-image-tag-digest.sh
 curl https://raw.githubusercontent.com/hanscees/dockerscripts/master/scripts/emailer.py > emailer.py
#-chmod them
   chmod +x *.sh
   chmod +x  *.py
#- install qs
  apt-get install jq

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.