Docker Tags should be Mutable

· 308 words · 2 minute read

Docker tags should be mutable, and your observability should account for the digest.

Images already have an immutable reference - the digest on their manifest. If it’s necessary to pin to a specific image, pin to the digest.

The tag should be representative of the application bundled, and not the libraries it bundles in the image. You should be able to deploy an image using the same application version with upgraded libraries and dependencies.

For an imaginary example, say your application depends on OpenSSL, and there’s a new zero-day vulnerability in the version of OpenSSL that’s bundled in your docker image. You need to build a new image with a patched version of OpenSSL, but nothing about the interface to OpenSSL has changed, and your application hasn’t changed. Only the dependent library in the container image needed to change.

In this scenario, building a new image and pushing to the same existing tag has the benefit that anything that pulls your image will begin to receive a patched version without having to update deployment configurations (barring image pull policies mandating using the existing cache forever).

The two best-benefited scenarios I have for this are for building on top of base images. For example, if I am building my app on top of :3.20.2, but there is a vulnerability that gets patched in :3.20.3, I would need to go change my FROM statement to :3.20.3. Referencing one of Alpine’s higher-level tags, like :3.20 would ensure that the next time I build my image, as long as I’m not getting a cached version on my build system, I get the patched version without having had to push changes to my Dockerfile. This would give me the ability to schedule rebuilds of my image, with the expectation that I’m potentially starting from a “more clean” base image each time I rebuild.