How to automatically update Docker containers when updating Dockerized web applications

Updating web applications is a common task for system administrators. Updating the containers they are in is another extra effort. Automate this and make life easier. Imagine this scenario. You host multiple web services running in Docker containers. When a web service releases a new version, you download the Docker image and update the containers to update the service. This is about updating the operating system containers themselves. Updating an OS running in a container manually can be difficult from time to time. To do this, you need to independently run the appropriate update commands in the running container. How about removing this extra step and combining the OS update with the service update? This is an automation trick I use when I update a web service deployed with Docker Compose.

We’ll be using Ghost CMS as a real-world example based on this deployment.

Automatic update of OS containers when updating a web service

You can just read this article to understand what we are doing. But if you want to follow it, you can do it too.

We will show two different examples:

  1. For Debian-based Docker containers
  2. For Alpine-based Docker containers

Automatic Updating of Debian Containers

The procedure requires you to complete two steps:

Step 1: pay attention to the CMD instruction

Notice the CMD statement that is finally listed inside the WebApp’s Dockerfile.

To do this, you need to check the Dockerfile with which the image was built (in this example, Ghost):

Hence the real command here is node current / index.js.

Step 2. Add the “Auto Update” option

Add update commands and the above CMD statement to the Ghost section of the Docker Compose file:

command: sh -c "apt update && apt -y upgrade && node current/index.js"

Let’s see how it will look in the end. Let’s say, for example, you are looking at the Docker Compose entries for the Ghost service from the tutorial above. An updated version based on our guide would be:

    ghost:
      image: ghost:4.20.4
      volumes:
        - ghost:/var/lib/ghost/content
        -./config.json:/var/lib/ghost/config.production.json
      command: sh -c "apt update && apt -y upgrade && node current/index.js"
      env_file:
        -./ghost-mariadb.env
      restart: on-failure
      depends_on: 
        - ghostdb
      networks:
        - net
        - ghost

Here we have specified the command right after the volumes section.

Alpine automatic container renewal

This procedure again requires you to follow two similar steps:

Step 1: pay attention to the CMD instruction

Notice the CMD statement that is finally listed inside the WebApp’s Dockerfile.

To do this, you need to check the Dockerfile (in this example Ghost Alpine):

How to automatically update Docker containers when updating Dockerized web applications

The command here is the same as seen on the Debian version earlier: node current / index.js.

Step 2. Add the “Auto-Upgrade” parameter

Add update commands and the above CMD statement to the Ghost section of the Docker Compose file:

command: sh -c "apk update && apk add --upgrade apk-tools && apk upgrade --available && node current/index.js"

Alpine Upgrade Guide

Let’s take a look at what it will look like in the end (note that this time we will be using the Alpine image for Ghost). Let’s say, for example, you are looking at the Docker Compose entries for the Ghost service from the tutorial above. An updated version based on our guide would be:

    ghost:
      image: ghost:4.20.4-alpine
      volumes:
        - ghost:/var/lib/ghost/content
        -./config.json:/var/lib/ghost/config.production.json
      command: sh -c "apk update && apk add --upgrade apk-tools && apk upgrade --available && node current/index.js"
      env_file:
        -./ghost-mariadb.env
      restart: on-failure
      depends_on: 
        - ghostdb
      networks:
        - net
        - ghost

That’s all. From now on, whenever you update your web applications without downtime, the container update commands will be automatically invoked and then your web applications will execute.

NOTE When updating any application by changing the version number of the image in the Docker build file, you must temporarily disable the command option discussed here using the hashtag. After the web application update is complete, re-enable the same line to update the container itself. Both of these steps (application and container updates) are achievable without downtime due to scalability.

Bonus tips

Here is a list of commands for other popular apps like Nextcloud and Rocket.Chat. Remember, they must be added exactly as you saw in the Ghost example.

Nextcloud

For Debian:

command: sh -c "apt update && apt -y upgrade && apache2-foreground"

For Alpine:

command: sh -c "apk update && apk add --upgrade apk-tools && apk upgrade --available && apache2-foreground"

Rocket.Chat

command: sh -c "apt update && apt -y upgrade && node main.js"

Hope this article will help you in your day-to-day activities as a sysadmin. If you have any questions, feedback or suggestions, please leave your thoughts in the comments section below.