Skip to main content

Docker compose update (and rollback)

·4 mins
Kristof Kovacs
Author
Kristof Kovacs
Software Architect & DevOps Consultant

Hello, I’m Kristof, a human being like you, and an easy to work with, friendly guy.

I've been a programmer, a consultant, CIO in startups, head of software development in government, and built two software companies.

Some days I’m coding Golang in the guts of a system and other days I'm wearing a suit to help clients with their DevOps practices.

Of course your critical systems should have either backups/snapshots (for example lxc snapshot), or a full deploy pipeline that allows you to revert to older versions in case of problems.

But sometimes you just don't, because you're running some non-critical thingy temporarily just as a simple docker-compose.yml.

Even in that case there should be some way to rollback/revert to the original version after update. Here's a short description of that.

NOTE: This was originally written when it was docker-compose. On more recent systems it's docker compose, but not yet everywhere. Works the same.

TLDR: #

NOTE: I'm running docker images; docker-compose images at every step just to have a visual snapshot of where we are.

UPGRADE:

docker images; docker-compose images
docker image prune -af  # remove any old images
docker images; docker-compose images
docker-compose pull     # pull images but dont restart
docker images; docker-compose images
docker-compose up -d    # recreates if neeeded

REVERT/ROLLBACK:

docker images; docker-compose images
docker-compose down                 # Stop everything (cant down only one container)
docker image rm IMAGENAME:latest    # delete current "latest" (can be hash)
docker tag OLDHASH IMAGENAME:latest # tag older as "latest"
docker images; docker-compose images
docker-compose up -d                # Start everything
docker images; docker-compose images

More in detail: #

1. Prune old images #

First we clean up any previous images that are NOT currently in use, to make our job easier later (and also to save disk space).

docker image prune -af  # remove any old images

Should look something like this:

Deleted Images:
untagged: nextcloud@sha256:2ab0c5de2afd33c55721e69e87bd1667cad6c4550ba0fd0303cfeb7abb260750
deleted: sha256:c79206d0ddb064615b2fc05b7b3272aa517e0bcc5926960a225642d58911c0df
deleted: sha256:6ce477082bc242c495c04ce886e3f505f559c9df6bdf6b59861f438c5964ee31
[...]
deleted: sha256:1387079e86adf524e7e92bada71d261d9ff58f34409751ab36560385262a8386

Total reclaimed space: 1.29GB

2. Remember the current latest hash (IMPORTANT!) #

docker images; docker-compose images

Should look something like this:

REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nextcloud    latest    0ef5d328122e   4 weeks ago   1.28GB
   Container      Repository    Tag       Image Id       Size
---------------------------------------------------------------
nextcloud_app_1   nextcloud    latest   0ef5d328122e   1.283 GB

Here we need to make note of the 0ef5d328122e, which is the current latest (or other tag you are using) image. We will roll back to this version if necessary.

Also make a note of the image name ("Repository"), nextcloud in this case, but it can be a more complicated one, like gitea/gitea, or even a full url like ghcr.io/hydradatabase/hydra or mcr.microsoft.com/playwright.

3. Download new image(s) #

Now download the latest image(s), but don't restart yet.

docker-compose pull     # pull images but dont restart
docker images; docker-compose images

Should look something like this:

Pulling app ... done
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nextcloud    latest    f940b54bd54f   39 hours ago   1.28GB
nextcloud    <none>    0ef5d328122e   4 weeks ago    1.28GB
   Container      Repository    Tag       Image Id       Size
---------------------------------------------------------------
nextcloud_app_1   <none>       <none>   0ef5d328122e   1.283 GB

Here you see our previous latest, 0ef5d328122e, and the new latest, which is f940b54bd54f. Make not of THIS hash too (this is the one we need to delete if things go wrong).

4. Restart with new image(s) #

docker-compose up -d    # recreates if neeeded

Should look something like this:

Recreating nextcloud_app_1 ... done

Now check your site. If everything is good (usually it is), you're done.

REVERT/ROLLBACK #

In case you need to revert/rollback, you'll need the OLD latest hash (0ef5d328122e in our case) and the name of the image (nextcloud in our case) and tag (latest in our case).

Start with seeing where we are at:

docker images; docker-compose images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nextcloud    latest    f940b54bd54f   40 hours ago   1.28GB
nextcloud    <none>    0ef5d328122e   4 weeks ago    1.28GB
   Container      Repository    Tag       Image Id       Size
---------------------------------------------------------------
nextcloud_app_1   nextcloud    latest   f940b54bd54f   1.282 GB

Here we see that we're running on the new image, but the old was is still downloaded (tagged as <none>).

Let's down the system:

docker-compose down     # Stop everything (can't down only one container)
Stopping nextcloud_app_1 ... done
Removing nextcloud_app_1 ... done
Removing network nextcloud_default

Let's delete the NEW image:

docker image rm nextcloud:latest    # delete current "latest" (can be hash)
Untagged: nextcloud:latest
Untagged: nextcloud@sha256:3a62c849b9ed64f8085d76c12f26376b0e9fc4fbcef8a20059e1e26b027469e5
Deleted: sha256:f940b54bd54f5f634aab39e82ce14987399af67b415bb6b988693999fc99b388
Deleted: sha256:e2c0f783d2468a2fe0cc33ea25678d77c35d1f9c663ffda70f1935203eea586c
[...]
Deleted: sha256:9853575bc4f955c5892dd64187538a6cd02dba6968eba9201854876a7a257034

Let's tag the OLD image as latest:

docker tag 0ef5d328122e nextcloud:latest    # tag older image as "latest"

No output for this one.

Let's see where we are:

docker images; docker-compose images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nextcloud    latest    0ef5d328122e   4 weeks ago   1.28GB
Container   Repository   Tag   Image Id   Size
----------------------------------------------

The old image is the latest. The system is not running. Let's start it back:

docker-compose up -d    # Start everything
Creating network "nextcloud_default" with the default driver
Creating nextcloud_app_1 ... done

Let's see where we are:

docker images; docker-compose images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nextcloud    latest    0ef5d328122e   4 weeks ago   1.28GB
   Container      Repository    Tag       Image Id       Size
---------------------------------------------------------------
nextcloud_app_1   nextcloud    latest   0ef5d328122e   1.283 GB

We see that the old image is running now.


Questions? Comments? Insults?
Feel free to drop me a line below, I love getting messages!