Upgrading ones Ghost blogging platform is easy when you are running it inside of a Docker instance. This post is a continuation of my previous post on how to set up Ghost Using Docker and Nginx. I will be upgrading to the Ghost 0.9.0 version, which is the latest at the time of writing. The instructions may be different if you are using a different Ghost Docker image besides the official Ghost image or if you have made modifications to the Docker image itself. Modifications to Ghost data, such as themes and blog posts, will be preserved. I will be discussing how to upgrade your Ghost Docker instance using simple Docker commands. We will be minimizing downtime of our running container the best we can although if you are looking for a truly zero-downtime deploy, you will need to get a little creative. Enough with the small talk, let's get to it!
Make a backup of your current Ghost Data
This step is precautionary but it is always good to have a backup! Make sure to backup
/var/lib/ghost/ if you have not already. You can do a compressed backup of all of your Ghost data with the following command.
tar -zcvf ghost.tar.gz /var/lib/ghost/
Pull the latest Docker Image
sudo docker pull ghost
This command will pull the latest Ghost image from the official Docker Hub repository and create a new Docker image using it. It will also update the image tags so that the image named "Ghost" will now be pointed to the latest Ghost image. If you run
sudo docker images you will see these changes. Also, if you run
sudo docker ps -a, you will see that the current running container will still be pointed to the old image ID.
Create the New Docker container
We are basically going to run the same command we ran in the last post to create a new Docker container. Since the pull we ran in the above section updated the tags, the newly created container will be using the latest Ghost image. One thing to note, we need to choose a different container name than what the old container is using. I decided to tack the Ghost version on the end but you could easily use a time stamp instead.
sudo docker create -p 2368:2368 --name ghost0.9.0 -v /var/lib/ghost/:/var/lib/ghost --restart=always ghost
When this successfully returns, you will now have two containers available. Run
sudo docker ps -a to make sure that the newly created container is pointed at the correct image ID.
The Old Stop and Start
At this point, we have two containers, one old container which is currently running and another updated container which is not. We cannot start the updated container while the other is running since both containers will try to bind to the same port. Instead, we are going to perform the old Docker switch-a-roo. This will consist of simply stopping the old container and starting the new container as quickly as possible. Hold my beer, I'm going in!
sudo docker stop ghost && sudo docker start ghost0.9.0
The stop command may take some time to complete. The start command on the other-hand, is much faster to complete. However, database migrations may take some time to complete on initial start. Once completed, do a quick
sudo docker ps -a to make sure that the containers have been swapped correctly.
In your browser, reload your Ghost webpage and notice that the banner stating there is an upgrade is now gone. Success! Take a look around and make sure you are satisfied with the upgrade.
Remove the Old Container
If everything checks out, you may now remove the container and image of the old instance that is no longer running. To do this use
sudo docker rm <container_name> and
sudo docker rmi <image_id>.
We have successfully updated our Ghost image in a very simple manner with little interruption to our blogging platform. Docker makes this straight-forward with simple commands that are similar to using a package manager or git. Pulling the latest Docker image for Ghost takes care of performing all of the other commands, such as npm package updates, that are normally associated with upgrading a node package. This is just another convenience that containers give a system administrator. The notion that containers are expendable makes upgrading a breeze.