How do I check if my local docker image is outdated, without pushing from somewhere else?
Asked Answered
P

5

32

I'm running a react app in a docker container, on a Coreos server. Let's say it's been pulled from dockerhub from https://hub.docker.com/r/myimages/myapp.

Now I want to check periodically if the dockerhub image for the app container has been updated, to see if the image I'm running locally is behind.

What would be the most efficient way to check if a local docker image is outdated compared to the remote image? All solutions I've found so far are bash scripts or external services that push on an update. I'd like to find a solution that is as native to docker as possible, and would like to refrain from pushing a notification from somewhere else (to alert the server of an updated image).

Perfume answered 9/2, 2017 at 13:3 Comment(6)
I could do a docker pull, and then grep the hash and compare that somehow. But that would be slow, resource intensive and rather brittle. I'd expect there to be a more robust solution, but haven't been able to find it.Perfume
Maybe this can help: #26424015Enantiomorph
Also, I know that I could let the docker host listen on a certain port, and then ping it when a new image has been built to trigger a pull. But for my current situation I'd like the check to be initiated from the docker host, instead of triggered by an external CI/CD pipeline.Perfume
@lorenzvth7 Also, that question is concerned with the base image, and not the image itself being outdated. Plus there is an accepted answer, but not a solution.Perfume
it's probably not possible to find the creation-time by one command. But with the provided docker API and some bash script (in cron) you're able to create a script to find the creation time for each version of an image on dockerhub and if it's updated you can update your image. It just requires a bit scripting.Enantiomorph
adding some different phrases for search keywords: How do I check if I have the latest Docker image? How do I check if an image has been updated on Docker Hub?Pseudaxis
S
11

You can query the registry API for the image digest and compare it to that of what you've pulled.

$ cat digest-v2.sh
#!/bin/sh

ref="${1:-library/ubuntu:latest}"
repo="${ref%:*}"
tag="${ref##*:}"
acceptM="application/vnd.docker.distribution.manifest.v2+json"
acceptML="application/vnd.docker.distribution.manifest.list.v2+json"
token=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull" \
        | jq -r '.token')
curl -H "Accept: ${acceptM}" \
     -H "Accept: ${acceptML}" \
     -H "Authorization: Bearer $token" \
     -I -s "https://registry-1.docker.io/v2/${repo}/manifests/${tag}"

$ ./digest-v2.sh library/busybox:latest
HTTP/1.1 200 OK
Content-Length: 2080
Content-Type: application/vnd.docker.distribution.manifest.list.v2+json
Docker-Content-Digest: sha256:d366a4665ab44f0648d7a00ae3fae139d55e32f9712c67accd604bb55df9d05a
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:d366a4665ab44f0648d7a00ae3fae139d55e32f9712c67accd604bb55df9d05a"
Date: Sun, 11 Oct 2020 21:04:59 GMT
Strict-Transport-Security: max-age=31536000

You can compare that ETag or Docker-Content-Digest header to the registry reference on the image you've previously pulled:

$ docker image inspect busybox:latest --format '{{json .RepoDigests}}' | jq .
[
  "busybox@sha256:d366a4665ab44f0648d7a00ae3fae139d55e32f9712c67accd604bb55df9d05a"
]

$ docker image pull busybox:latest
latest: Pulling from library/busybox
Digest: sha256:d366a4665ab44f0648d7a00ae3fae139d55e32f9712c67accd604bb55df9d05a
Status: Image is up to date for busybox:latest
docker.io/library/busybox:latest

I've also been working on some Go APIs and CLI to work with more registries where you may need to pass different types of authorization. That project is at regclient/regclient and includes a regctl command.

$ regctl image digest --list busybox:latest
sha256:d366a4665ab44f0648d7a00ae3fae139d55e32f9712c67accd604bb55df9d05a
Samora answered 11/10, 2020 at 21:9 Comment(1)
A gist with the results of my examination of the issue.Contributory
I
6

If you are using Docker Hub you could use a Webhook to notify the docker host about a update, and take action over that.

Using the webhook would be the "simple" way to do it (I think) otherwise you would have to do some kind of crawling in the docker pull or as explained by @alebianco comparing some hashs or build/creation dates.

Here is the docs about it: https://docs.docker.com/docker-hub/webhooks/

Iraqi answered 19/2, 2017 at 11:25 Comment(2)
So basically pulling whether or not a container is outdated isn't easily doable, and the best current solution is to push a notification from a build server or something similar. Strange that the former functionality doesn't exist.Perfume
you could always do a docker pull your/image:tag, and evaluate if the image has changed, and then remove the old container and run a new one with the updated image... to be true I do not use the Docker Hub webhook or do any kind of update check, I use Deploybot or other deploy service that will trigger the server deploy when GitHub or Bitbucket notify him about a change in masterIraqi
S
4

there's an API available for the Docker Hub

You should be able to get the list of tags, and from there the manifest details


edit

I did some digging around, looks like they don't expose any kind of checksum of the image, it's manifest or the layers that compose it.

The closest thing i found is the creation date ... which i wouldn't suggest using if you're trying to make something remotely secure.

Anyway, you need to get an access token first

curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull"

extract the token from the response, then you can load the manifest of an image version

curl --header "Authorization: Bearer $TOKEN" https://index.docker.io/v2/library/ubuntu/manifests/latest

look into the history object of the json returned, you'll find a created property.

Then you can get your local image created date with

docker inspect --format "{{json .Created}}" ubuntu:latest

Compare the two and cringe away ...

Supermarket answered 9/2, 2017 at 13:51 Comment(4)
So what exactly would your suggested solution be? Curl a certain endpoint and compare the result to the local image?Perfume
Thanks for the answer. Ok so so far all the suggested answers are pretty prone to breaking, so it seems like there just isn't a good way of doing this yet. Opened an issue in the docker repo to see if this is an intentional missing feature: github.com/docker/docker/issues/30906Perfume
There is also the Image property in the history objects and in the docker inspect output. It should be pretty safe to compare these. Also, using this API should also be safe, at least to some degree. It's the official registry API and thus will be stable for long time. The only problem is...the history object contains v1Compatibility object which actually hold the Image property. And that sounds like something that may be removed in the future. But maybe you are fine with using this until the docker issue you posted is resolved.Raylenerayless
It looks like this method gives the hash of all the fs layers involved in the image. In theory you could get a single hash with curl -sS -H "authorization: Bearer ${token}" "https://index.docker.io/v2/library/${imagename}/manifests/${tagname}" | jq --raw-output '.fsLayers[] | .blobSum' | cut -d' ' -f1Rickie
U
1

Issue 30906 (Docker command to check if a local container image is outdated?) just mentioned (in Jan. 2023):

You can try using Diun for this task.
It checks for updates and then can notify you via a number of providers.

Docker Image Update Notifier is a CLI application written in Go and delivered as a single executable (and a Docker image) to receive notifications when a Docker image is updated on a Docker registry.

With Go, this can be done with an independent binary distribution across all platforms and architectures that Go supports.

See Marco d'Aleo blog post "DIUN: Docker Image Update Notifier"

Diun supports many services, but for this kind of projects I usually choose Telegram.

Uranometry answered 21/1, 2023 at 0:24 Comment(0)
M
-1

I solved this issue with a crawler that checks either the Dockerfile directly or a from string.

I backed everything into a docker image which could be found in the docker hub.

I simply run the image in my gitlab ci pipeline. If the base image is outdated is prints all newer versions so that you can easily pick the tag.

Link: https://hub.docker.com/r/olafnorge/docker-image-crawler/

Manger answered 15/5, 2017 at 8:4 Comment(2)
That link is dead. Did the solution not work out? Curious :)Parmentier
@BarryO'Neill I got rid of the approach as I now build images more frequent and use sem ver with major.minor from upstream and not as fine grained (major.minor.patch) as at the time I was writing my comment.Manger

© 2022 - 2024 — McMap. All rights reserved.