Atlantic.Net Blog

How to Update Docker Container with Zero Downtime

In a Dockerized environment, you are using multiple images and working with many containers. When you run a container from an image, it continues running that version because Docker images do not update automatically. You may need to update it manually. It is always recommended to run a container from the latest Docker image.

In this guide, we will show you hands-on examples of how to update a running container with zero downtime.

Step 1 – Install Docker CE and Docker Compose

First, install all required dependencies with the following command:

apt-get update -y
apt-get install git apt-transport-https ca-certificates curl software-properties-common -y

Next, add the Docker GPG key and repository with the following command:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

Once the repository has been added, install the Docker and Docker compose with the following command:

apt-get install docker-ce docker-compose -y

Once both packages are installed, you can proceed to the next step.

Step 2 – Create a Docker Compose File

For the purpose of this tutorial, we will create a docker network, volume, and a docker-compose.yml file to deploy a Ghost container.

First, create a network named net and volume named ghost using the following command:

docker network create net
docker volume create ghost

Next, create a directory for the Ghost project with the following command:

mkdir Ghost

Next, change the directory to Ghost and create a docker-compose.yml file:

cd Ghost
nano docker-compose.yml

Add the following lines:

version: '3.5'
services:
  ghost:
    image: ghost:3.36
    volumes:
      - ghost:/var/lib/ghost/content
    environment:
      - VIRTUAL_HOST=ghost.example.com
      - url=http://ghost.example.com
      - NODE_ENV=production
    restart: always
    networks:
      - net

volumes:
  ghost:
    external: true

networks:
  net:
    external: true

Save and close the file when you are finished.

The above file will download the Ghost image version 3.36 and create a Ghost container for domain ghost.example.com.

Step 3 – Create a Ghost Container

Now, change the directory to Ghost and launch the Ghost container using the following command:

docker-compose up -d

You should get the following output:

Pulling ghost (ghost:3.36)...
3.36: Pulling from library/ghost
bb79b6b2107f: Pull complete
99ce436c3449: Pull complete
f7bdc31da5f5: Pull complete
7a1300b9ff59: Pull complete
a495c68fa838: Pull complete
6e362a39ec35: Pull complete
b68b4f3c36f7: Pull complete
41f8b02d4a71: Pull complete
3ecc736ea4e5: Pull complete
Digest: sha256:595c759980cd22e99037811397012908d89efb799776db222a4be6d4d892917c
Status: Downloaded newer image for ghost:3.36
Creating ghost_ghost_1 ... done

You can check the Ghost image with the following command:

docker images

Output:

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ghost        3.36      455ce1645479   4 months ago   440MB

You can also check the Ghost container with the following command:

docker ps

Output:

CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS          PORTS      NAMES
d4b51b1aafc8   ghost:3.36   "docker-entrypoint.s…"   23 seconds ago   Up 20 seconds   2368/tcp   ghost_ghost_1

Step 4 – Update the Docker Compose File

In this section, we will update the Docker compose file and change the Ghost version from 3.36 to 3.37.1:

nano docker-compose.yml

Make the following changes:

version: '3.5'
services:
  ghost:
    image: ghost:3.37.1
    volumes:
      - ghost:/var/lib/ghost/content
    environment:
      - VIRTUAL_HOST=ghost.example.com
      - url=http://ghost.example.com
      - NODE_ENV=production
    restart: always
    networks:
      - net

volumes:
  ghost:
    external: true

networks:
  net:
    external: true

Save and close the file when you are finished.

Step 5 – Launch a New Ghost Container

Now, we will use the scaling method to create a new Ghost container without affecting the older Ghost container. You can do it with the following command:

cd Ghost
docker-compose up -d --scale ghost=2 --no-recreate

You should get the following output:

Pulling ghost (ghost:3.37.1)...
3.37.1: Pulling from library/ghost
bb79b6b2107f: Already exists
99ce436c3449: Already exists
7f4b5e228565: Pull complete
de71eab7febf: Pull complete
29961d2eb573: Pull complete
923f84e249ab: Pull complete
dfad6f73fc3d: Pull complete
b16cf83b3022: Pull complete
387b2254843c: Pull complete
Digest: sha256:fad0c2631cbba3d6c61da6fa5ef39da201780f2ae64ce51f3d5ebb412ca2564b
Status: Downloaded newer image for ghost:3.37.1
Starting ghost_ghost_1 ... done
Creating ghost_ghost_2 ... done

You can check the new Ghost image with the following command:

docker images

Output:

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ghost        3.37.1    c64d108acdfe   3 months ago   439MB
ghost        3.36      455ce1645479   4 months ago   440MB

You can also check the new Ghost container with the following command:

docker ps

Output:

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS      NAMES
c21550f39440   ghost:3.37.1   "docker-entrypoint.s…"   33 seconds ago   Up 31 seconds   2368/tcp   ghost_ghost_2
d4b51b1aafc8   ghost:3.36     "docker-entrypoint.s…"   4 minutes ago    Up 4 minutes    2368/tcp   ghost_ghost_1

Step 6 – Scale the New Ghost Container

At this point, both Ghost containers are running using the same configuration. Now, we will stop and remove the old Ghost container.

docker container stop ghost_ghost_1
docker container rm ghost_ghost_1

Now, run the following command to scale down the configuration to its original setting:

cd Ghost
docker-compose up -d --scale ghost=1 --no-recreate

You can also check the new Ghost container log for more information.

docker logs ghost_ghost_2

Output:

[2021-03-05 04:50:13] INFO Blog is in maintenance mode.
[2021-03-05 04:50:13] INFO Ghost is running in production...
[2021-03-05 04:50:13] INFO Your site is now available on http://ghost.example.com/
[2021-03-05 04:50:13] INFO Ctrl+C to shut down
[2021-03-05 04:50:13] INFO Ghost boot 3.581s
[2021-03-05 04:50:13] INFO Creating database backup
[2021-03-05 04:50:13] INFO Database backup written to: /var/lib/ghost/content/data/ghost.ghost.2021-03-05-04-50-13.json
[2021-03-05 04:50:13] INFO Updating portal button setting to false
[2021-03-05 04:50:13] INFO Blog is out of maintenance mode.

Your Ghost container is now updated with a new Ghost image.

Conclusion

In the above guide, you learned how to update the Docker container without any downtime. Get started with updating your Docker container on VPS hosting from Atlantic.Net!

Get a $250 Credit and Access to Our Free Tier!

Free Tier includes:
G3.2GB Cloud VPS a Free to Use for One Year
50 GB of Block Storage Free to Use for One Year
50 GB of Snapshots Free to Use for One Year