How to keep docker images up to date?

Viewed 4840

I'm fairly new to docker and try to implement automated deployment. As far as my understanding goes, containers should never be updated. In case of updates, new images need to be created (1) and running containers need to be replaced by new instances (2).

I solved challenge 2 by using containrrr/watchtower. This seems to be the only(?) still maintained software on automatically updating my containers with newer versions.

Challenge 1 is a bit more complex. For images directly out of the docker hub there is not much I can do besides hoping for regular updates by package maintainers. However in some cases the images from docker hub are not sufficient and it's often recommended to create derived images. Sometimes there are no maintained images in the first place. For both use cases I set up Jenkins pipelines which build the images and pushes them into my private docker repository, monitored by watchtower. So far, so good.

But how do I setup the trigger on my Jenkins pipelines to keep them up to date?

Possible sources:

  • VCS (SVN/GIT): Handled by Jenkins easily.
  • Docker Hub (For derived images or bases): The only workaround I found was to create a dummy Docker Hub repository with a dummy Github repository, automated builds for repository links ("Enable Base Image") and then a web hook to my Jenkins instance ("CloudbDocker Hub/Registry Notification plugin")
  • Package updates (Installed in the docker file. E.g. via apk/apt): Here I did not find any solution yet.

I'm very surprised that there is not more information on this topic. There are so many great guides on how to initially setup docker and Jenkins which show how easy it is to get started but nothing on how to run containers for a prolonged time. For many developers I assume this is not an issue as there are many updates in the source code which trigger an update anyway often enough but what about all the custom made images?

Is this an actual gap or am I missing an essential piece of information?

1 Answers

As far as my understanding goes, containers should never be updated. In case of updates, new images need to be created (1) and running containers need to be replaced by new instances.

Let's make a quick introduction to docker first:

Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security allow you to run many containers simultaneously on a given host. For more info: Docker documentation

It is a common misconception to thing about a container as a virtual machine, but docker is not a virtualization technology, it’s an application delivery technology. The abstraction of the container is the service running of your application, and once the process ends, the docker container is stopped.

Each container have its own isolated environment prepared for the needs of the service to run. This is one of the main benefits of docker, you can REPLICATE the environment of the application to run. This quick introduction was done to understand this benefit of docker, to be as a base for the clarification of your question. With this in mind, lets see your question:

  1. For images directly out of the docker hub there is not much I can do besides hoping for regular updates by package maintainers

Why do you need to update your running containers from images directly out of docker hub?

Imagine you are using a postgres image to run a db in your server. Other container needs to communicate with this postgres container so it needs access to this db. You application is working as expected with current image version. There is a new available version of the postgres image, your system updates the container and for some reason, the container behaviour is not the same as previous version, and once the container is updated, your application fails for some reason.

The main thing here is that updating a container should be done with criterion, understanding the needs of your application, and always having a way to test that this updated version behaves in the way you expect. On the other hand, if you update automatically without any criterion and without previous assertion of the entire application, you are not taking advantage of the environment replication.

  1. However in some cases the images from docker hub are not sufficient and it's often recommended to create derived images

And this is strongly related to the first point. Since I want to create my isolated environment for the application needs, I need to choose the suitable base image to build my final image. I would update this base image only under specific criterion.

Imagine I want to create a container for java application. I will use as base image an official java image. I will chose the version of the image with the suitable sdk of my project. If this image is automatically update for a newer sdk, this can break the current behaviour of the application.

But how do I setup the trigger on my Jenkins pipelines to keep them up to date?

With all previous clarifications, the answer is: this should be a manual step, done under criterion for the container service needs and having a way to test that this new image version, being a base image for your final image, or being used directly in your system, does not break your application or system behaviour.

I used environment replication docker benefit to answer your question, but there are a lot of other docker capabilities, standard processes and others that play an important role that would make the answer much more longer. I hope this can be a good introduction for your question.

I encourage you to read about best practices of writing docker images, and other interesting blogs about docker to better understand the benefits of using this technology, and gain knowledge so that the answer makes more sense. I will left a couple of interesting links below:

  1. https://www.docker.com/blog/intro-guide-to-dockerfile-best-practices/
  2. https://www.docker.com/blog/containers-are-not-vms/
Related