How to Upgrade Docker Containers Automatically When Updating Dockerized Web Apps
Imagine this scenario. You host a few web services running in Docker containers. When the web service has a new version release, you fetch the Docker image and update the containers to update the service.
I have discussed updating Docker containers without downtime earlier but this article is not about upgrading the web apps. This one is about updating the operating system containers themselves.
Upgrading the OS running in the container manually can be a daunting task from time to time. You must run the relevant upgrade commands yourself on a running container separately to make that happen.
How about eliminating this extra step and combine the updating of OS along with the updating of the service?
This is an automation trick I use when I update a web service which was deployed with Docker Compose.
We'll use Ghost CMS as a real-world example based on this deployment.
Upgrading OS containers automatically while updating the web service
You can just read this article to understand what I am doing. But if you want to follow it along, you can do that as well.
I will show two different examples:
- For Debian Based Docker Containers
- For Alpine Based Docker Containers
Automatically Upgrading Debian Containers
The procedure needs you to take care of two steps:
Step 1: Note The CMD Instruction
Make a note of the CMD instruction that is specified finally inside the WebApp Dockerfile.
To do this you need to check the Dockerfile with which the image was built (Ghost for this example):
Therefore, the actual command here is node current/index.js
.
Step 2: Add The "Auto-Upgrade" Setting
Add the upgrade commands and the noted CMD instruction inside the Ghost service section of the Docker Compose file:
command: sh -c "apt update && apt -y upgrade && node current/index.js"
Let's see how that would finally look like. Say, for example, you consider the Docker Compose entries for the Ghost service from the guide cited above. An updated version based on our tutorial 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, I've specified the command just after the volumes
section.
Automatically Upgrading Alpine Containers
This procedure once again needs you to take care of two similar steps:
Step 1: Note The CMD Instruction
Make a note of the CMD instruction that is specified finally inside the WebApp Dockerfile.
To do this you need to check the Dockerfile (Ghost Alpine for this example):
Very apparently, the command here is the same as seen for the Debian version earlier: node current/index.js
.
Step 2: Add The "Auto-Upgrade" Setting
Add the upgrade commands and the noted CMD instruction inside the Ghost service 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 Reference.
Let's see how that would finally look like (note this time that I'll use the alpine image for Ghost). Say, for example, you consider the Docker Compose entries for the Ghost service from the guide cited above. An updated version based on our tutorial 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 it then. From this point onwards, whenever you update your WebApps without downtime, the container upgrade commands would automatically get invoked and then your web apps would be executed.
Note: When updating any app by changing the version number of the image in the docker compose file, you must temporarily disable the command option that is discussed here with a hashtag. Once the update in done for the web app, re-enable the same line to update the container itself. Both these steps (updating the app and the container) are achievable without any downtime through scaling.
Bonus Tips
Here is a list of commands for other popular apps like Nextcloud and Rocket.Chat. Remember, these are to be added just like how you saw for 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 helps you in your day-to-day sysadmin activities. If you have any queries, feedback or suggestions, please leave your thoughts in the comment section below.