How to upgrade docker container with previous network and volumes?

Introduction

This article is focused on the upgrading mechanism of container images. There are various methods to upgrade a container to its newest image. Here we have used some of the simple and easy-to-use methods. First, we discussed the manual method for a quick test. Then we tried some automatic methods. These methods will monitor the image and if any new update is present, they create a new container with the updated image.

Methods

  • Manually but using CLI

  • Automatic but using CLI

  • Automatic but using Docker Compose

Manually but using CLI

Here we are going to follow the below steps to achieve the goal of an image upgrade.

  • Create a container with the old image

  • Download the updated image on the local system

  • Create a new container with the updated image but with old volumes and networks

  • Delete the old container

Step 1: Create an old image Docker container

Use the below command to create a busybox container.

Example

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">$ docker run -itd --name old_cont --volume myvolume:/volumes --network
mynetwork busybox:unstable
</div>

Output

eb08fe5971190abc85aa7ca8ed44d1d85e6ea0fafeda26bb59785897bbd056ae

Get inside this image and create a file inside the volume directory.

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">$ docker exec -it old_cont sh
/ # cd volumes/
/volumes # touch myfile.txt
/volumes # ls
myfile.txt
/volumes # exit
</div>

Step 2: Create a container with the new image

This container has the latest image of the busybox.

Example

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">$ docker run -itd --name new_cont --volume myvolume:/volumes --network mynetwork busybox:latest
</div>

Output

ab15dea992f46c27dfdb4a290e2dec3fbb10b3821694dbc12f18935d9e651c20

Get inside the new container and check if the data is present.

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">$ docker exec -it new_cont sh
/ # cd volumes/
/volumes # ls
myfile.txt
/volumes # exit
</div>

Hence the volume and the network remain the same. Only the image of the container is changed to the latest.

Step 3: Remove the old container

Example

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">$ docker rm -f old_cont
</div>

Output

old_cont

In the next method, we are going to automate the above process with the help of the "watchtower" image.

Automatic but using CLI

Here we will take help from an extra image called "watchtower". This "watchtower" will check if any updated image is available on the repository. As soon as any update is pushed to the repository this watchtower will automatically download the updated image and create a newly updated container with all the old data that was linked to the old container.

Step 1: Create a container

First of all, we need to create a container with the old image.

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">docker run -itd --name old_cont busybox:unstable
unstable: Pulling from library/busybox
2461e8255644: Pull complete
Digest:
sha256:f4ed5f2163110c26d42741fdc92bd1710e118aed4edb19212548e8ca4e5fca22
Status: Downloaded newer image for busybox:unstable
81470b0f373557b3cb057e86113f6e11ce0baec23844e1370f519e043ff3db53
</div>

The container is created and running.

Step 2: Now create the watchtower container

Here create the "watchtower" container and add the name of the above container for upgrading.

Example

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">$ docker run -itd --name watch_container -v
/var/run/docker.sock:/var/run/docker.sock containrrr/watchtower old_cont
</div>

Output

Unable to find image 'containrrr/watchtower:latest' locally
latest: Pulling from containrrr/watchtower
560f024ada32: Pull complete
03aa1c411c91: Pull complete
4e2295fcaa5d: Pull complete
Digest:
sha256:897304ffb41533954deda3ca9dd140fa1ca41e5d7e0bc6d6352606931145779c
Status: Downloaded newer image for containrrr/watchtower:latest
db82aafdb60ed17b3faf8d6df138aead91f9483257febc02af96ba4ed53d225d

Now this will take care of everything, whenever the busybox:unstable is updated on the docker hub, watchtower will automatically upgrade this container to the updated image.

Automatic but using Docker Compose

we will create a Docker Compose file. This compose file will have multiple containers that need to be monitored. One container of "watchtower" will monitor all these containers. Whenever there is an update in the image of any of the containers, it will create a new container for that image.

Step 1: Create a Docker Compose file

Docker compose contains a total of three services or containers. Two containers "old_cont" and "test_cont" are monitored by the third container "watch_cont".

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">version: "3"
services:
   old_cont:
      image: busybox:latest
      container_name: busybox_container
      command: sleep infinity

   test_cont:
      image: busybox:unstable
      container_name: testing_container
      command: sleep infinity
   watch_cont:
      image: containrrr/watchtower
      container_name: watchtower_container
   volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      command: --interval 60 busybox_container testing_container
</div>

The watchtower will wait for 60 seconds a check if any updated image is present on the docker hub repository. If we do not give the --interval option then it will wait for 24 hours.

Step 2: Start the containers

To start all these containers use the below command.

<div class="code-mirror  language-docker" contenteditable="plaintext-only" spellcheck="false" style="outline: none; overflow-wrap: break-word; overflow-y: auto; white-space: pre-wrap;">$docker compose up -d
</div>

This will create and run all these containers in detached mode.

Conclusion

We were successfully able to create an upgrade cycle for the container. Even though these methods are not used in the production environment because we have dedicated software for this task. Some advanced tools are used for the task of updates and upgrades.

Updated on: 2023-01-05T15:41:26+05:30

528 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements