Upgrade your blog from Ghost 3.x, 4.x to Ghost 5
Photo by Clint Patterson / Unsplash
You run your blog on Ghost 3.x, 4.x using the Docker image, and you want to migrate to version 5, released in May 2022; this post is for you.
Ghost 5 brings many improvements that enhance the experience of both the blogger and visitors/members. Here are some features released:
- Multiple newsletters on a single website
- Offer more ways for your audience to become paid subscribers
- Support for Grammarly in the Ghost editor
- Advanced member filtering and bulk actions
- 12 new editor cards, including gifs, buttons, callouts, audio and video
- Learn more on this post.
On the technical side, Ghost 5 requires MySQL 8 as the database, meaning that coming from 3.x, or 4.x that use MySQL 5, you need to perform this upgrade while reducing the downtime of your website.
As a great fan of Ghost, I will show how I upgraded my blog.
If you are starting your blogging journey and want to self-host your blog with Ghost, I write a complete guide on how to set it up.
My current setup
I run my blog using Docker Compose, and here is the YAML configuration called blog.yml
:
version: '3.1'
services:
ghost:
image: ghost:4.47.0
restart: always
ports:
- 8080:2368
volumes:
- ~/data/content:/var/lib/ghost/content
environment:
# see https://ghost.org/docs/config/#configuration-options
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: secret_password
database__connection__database: ghost
url: https://blog.tericcabrel.com
NODE_ENV: production
db:
image: mysql:5.7
restart: always
volumes:
- ~/data/db:/var/lib/mysql
ports:
- "33060:3306"
environment:
MYSQL_ROOT_PASSWORD: secret_password
MYSQL_DATABASE: ghost
MYSQL_USER: user
MYSQL_PASSWORD: user_secret
OBVIOUSLY, I CHANGED THE CREDENTIALS
The configuration of this file creates two containers, one for the Ghost and the other for the database of the MySQL 5 image.
To upgrade to Ghost 5, here are the steps:
Back up the running database
All the posts, tags, pages, users, etc... are stored in the database, and we must back them up before upgrading to MySQL 8
MySQL client provides a tool to back up and restore a database called mysqldump. We will install it on the server; follow this post to install it on a Ubuntu server.
Once installed, run the command below to back up the database:
mysqldump -u root -p -P 33060 -h 127.0.0.1 ghost > blog.sql
The database content will be stored in the file named blog.sql
.
Create a Docker container from the MySQL 8 image
Execute the command below to start a container from the MySQL 8 image:
docker run --name db-blog -e MYSQL_ROOT_PASSWORD=secret_password -e MYSQL_DATABASE=ghost -v ~/data-db8/db:/var/lib/mysql -p 33070:3306 -d mysql:8.0.30
The most interesting part of this command is the option -v, which specifies the volume path to store the database configuration on the physical host.
By doing this, if we restore the data in the database, stop the container and start a new one with the same volume, the new container will reuse the configuration of the previous image, including the data stored inside.
Restore the data dump in the MySQL 8 database
The container for MySQL 8 is now running; let's restore the data in the file blog.sql
inside:
mysql -u root -p -P 33070 -h 127.0.0.1 ghost < blog.sql
Stop the Docker container of MySQL 8
We don't need this container so let's stop and delete it. The database configuration will still exist on the physical in the folder ~/data-db8/db
.
docker stop db-blog
docker container prune
Duplicate the Docker-compose
The docker-compose configuration file that runs our blog is named blog.yml
let's duplicate it and edit the duplicated one. This will make it easy to rerun the previous configuration if the new one doesn't work.
cp blog.yml blog-upgrade.yml
Upgrade the version of Ghost and MySQL
Open the file blog-upgrade.yml and update the docker image version to match the following:
version: '3.1'
services:
ghost:
image: ghost:5.8
restart: always
ports:
- 8080:2368
volumes:
- ~/data/content:/var/lib/ghost/content
environment:
# see https://ghost.org/docs/config/#configuration-options
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: secret_password
database__connection__database: ghost
url: https://blog.tericcabrel.com
NODE_ENV: production
db:
image: mysql:8.0.30
restart: always
volumes:
- ~/data/db:/var/lib/mysql
ports:
- "33060:3306"
environment:
MYSQL_ROOT_PASSWORD: secret_password
MYSQL_DATABASE: ghost
MYSQL_USER: user
MYSQL_PASSWORD: user_secret
Pull the Docker image of ghost 5.8
We manually pull the Docker image of Ghost 5.8 to reduce the time it will take to have the blog up and running.
docker pull ghost:5.8
Stop running the blog with docker-compose
This command will make your blog down, so make sure to run it quickly as possible:
docker-compose -f blog.yml down
Start the new docker-compose configuration
Run the command below to start Ghost 5 with MySQL 8
docker-compose -f blog-upgrade.yml up -d
The containers will take 15 - 30 seconds to be up and running.
Navigate to your blog URL, and everything will work as expected 🎉.
Follow me on Twitter or subscribe to my newsletter to avoid missing the upcoming posts and the tips and tricks I occasionally share.