Wednesday, November 20, 2024

How to Keep Docker Containers Updated

If you are running more and more Docker containers, and I see many in-home labs and business environments that are doing just that, one of the challenges that you will note when you start running containers at scale across many Docker hosts is lifecycle management. Keeping your containers updated is a necessity for security and keeping updated with the latest features. Let’s look at three ways that you can use to keep Docker containers updated.

Ways to keep Docker containers updated

Let’s look at three ways to keep Docker containers updated and see the pros and cons of each.

  1. Cron script with homegrown compose file
  2. Watchtower
  3. Portainer Business Edition web hooks

1. Cron script with homegrown compose file

With a bit of bash shell scripting and a Compose file, we can schedule the updating of our containers using a CRON job. To do this, you need the following:

  • A Docker compose file
  • A shell script with your commands that will run
  • CRON to run the shell script

The Docker Compose file is the same as the one you used to provision your containers. Below is just a snippet.

version: '3'
services:
  my_service:
    image: my_image:latest
    restart: always
    ...

Next, you need a shell script that will contain the commands that will be run by the CRON job below. As you can see:

  • We have the path to the compose file
  • We pull the latest images
  • We stop the running containers
  • Finally we restart the containers after pulling the newest images
#!/bin/bash

# Navigate to the directory containing your docker-compose.yml file
cd /path/to/your/docker-compose

# Pull the latest images
docker-compose pull

# Stop the running containers
docker-compose down

# Restart the containers with the new image
docker-compose up -d

2. Watchtower

The next way we can schedule container restarts and updates is using a utility that I have used for quite some time, called Watchtower. Watchtower is a great way to schedule and update your running containers.

watchtower container update solution
watchtower container update solution

The Watchtower container update solution is a container itself that you provision and it “watches” all the other containers on your Docker host and then checks the image repository for new images at the specified time that you schedule. If a new image is found, it stops the running container, pulls the new image and respins the container with the new image. Your persistent data isn’t affected.

You can learn more about Watchtower container updates here: Watchtower (containrrr.dev).

Watchtower commands

You can provision and schedule Watchtower using a Docker run command or using Docker Compose code. Let’s walk through the code on both as they are the same just with the appropriate syntax for each:

  • We are setting the label and giving it access to docker.sock to interact with other containers
  • The WATCHTOWER SCHEDULE sets when you want the updates to happen. This is similar to CRON format.
  • Set your timezone
  • CLEANUP means you want it to prune off the old images
  • Then we are setting up the email parameters for the rest of the block:
    • FROM address, TO address, EMAIL server, port, and delay

Docker run:

docker run -d \
  --name watchtower \  
  --label=com.centurylinklabs.watchtower.enable=false \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e WATCHTOWER_SCHEDULE="0 0 2 * * *" \
  -e TZ=America/Chicago \
  -e WATCHTOWER_CLEANUP=true \
  -e WATCHTOWER_NOTIFICATIONS=email \
  -e [email protected] \
  -e [email protected] \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=<IP or domain name> \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=25 \
  -e WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2 \
  containrrr/watchtower

Docker compose:

version: "3" 
services: 
  watchtower:     
    image: containrrr/watchtower
    container_name: watchtower 
    restart: always 
    environment: 
      WATCHTOWER_SCHEDULE: "0 0 2 * * *" 
      TZ: America/Chicago 
      WATCHTOWER_CLEANUP: "true" 
      WATCHTOWER_DEBUG: "true"      
      WATCHTOWER_NOTIFICATIONS: "email" 
      WATCHTOWER_NOTIFICATION_EMAIL_FROM: "[email protected]"
      WATCHTOWER_NOTIFICATION_EMAIL_TO: "[email protected]" 
      # you have to use a network alias here, if you use your own certificate 
      WATCHTOWER_NOTIFICATION_EMAIL_SERVER: "<IP or domain name>" 
      WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: "25" 
      WATCHTOWER_NOTIFICATION_EMAIL_DELAY: 2 
    volumes: 
      - /var/run/docker.sock:/var/run/docker.sock

3. Portainer Business Edition web hooks

Portainer is a tool that I have been particularly fond of since discovering it and it has exploded in popularity across the board. Most home labbers are using it in their environment and it is a great tool for organizations to use as well with many features. Also, it makes the learning curve with Docker much easier since it is a point and click GUI interface, that still lets you interact with the command line if you choose.

Portainer Community Edition (CE) is free. However, Portainer offers a 3-node Business Edition license which is an excellent place to start for home labs and provides additional capabilities that we will talk about next. You can learn more and sign up for that here:

With Business Edition, one of the things you can do is turn on the web hook and then send an unauthenticated post request to recreate the container with automation.

Again this is a business edition feature. If you look at this in community edition, you will see the following:

business edition feature for web hooks
business edition feature for web hooks

However, in Business Edition, we are able to flag this on. You will have the ability to easily click the Copy link button to copy the link.

with business edition turning on web hook and getting the uri
with business edition turning on web hook and getting the URI

If we hover over the information text, we will see the description of the webhook. Also, note the container has been running for 9 days.

viewing the information on the webhook and restarting the container
viewing the information on the webhook and restarting the container

Since we have generated the URI, let’s hop over to Postman and send a blank Post request to the special URL.

sending the post request using postman to the webhook uri
sending the post request using postman to the webhook uri

Hopping back over to Portainer, we see after a moment the container is restarted and we see it has been running for 2 minutes, so the post request worked! Cool.

container is restarted with the post request
container is restarted with the post request

Wrapping up

There are a number of ways to keep your Docker containers updated. You can use a CRON job with a Bash shell script, or Watchtower which is also a great solution for keeping containers updated. However, Portainer, provides a really slick solution to this as well with the Business Edition of the product. It is a shame this isn’t a feature available in the Community Edition. But, Portainer does generously give away a 3 node license for Portainer Business Edition which is great for home labs or even small organizations, SMBs, etc.

Brandon Lee
Brandon Leehttps://tek2cloud.com
Brandon Lee is the Senior Writer, Engineer and owner at tek2Cloud.com and has over two decades of experience in Information Technology. Brandon holds multiple industry certifications and loves IT automation, modern applications, and cloud technologies along with traditional servers and infrastructure.

Leave a Reply

Read more

Other Posts