This was actually relatively painless for me! I was on Ghost 0.7.x and updated to 0.9.x with no troubles. Since I have no idea how you set up your Ghost container, it is assumed you followed my previous post about Ghost and Docker. There shouldn't be anytime too crazy in there. The important thing is that your data is stored outside of your Ghost container. If it is not then fix this before attempting the commands below.

BACKUP YOUR DATA!

Lots of things can go wrong and unless you don't mind data loss then you better keep a backup. Ghost makes this super easy. Under the Labs page you can export your entire blog into a single JSON file. That means posts, images, tags... everything! I will be using the related import function to get the data back into the blog. There might be other ways to get the data updated or back into Ghost, but I did not try them.

Since I am paranoid about what can go wrong I also made a copy of all my ghost data from the server itself. This way I have a second way to restore data should everything suddenly catch on fire.

A Clean Slate

Some more words before we get to the actual commands. The following results in a fresh container from the latest ghost image. Initially, there will likely not be any of your data as we destroy the current Ghost container. We are basically starting a fresh Ghost container - an admin user will need to be set up as well. It is probably a good idea to not publicly expose the blog during this time (at least until the admin is set up again).

First, grab the latest Ghost image with docker pull ghost.

Once the pull is complete, you will want to stop the current container and then remove it. You can check what containers you have by running docker ps -a. In this case the container is named ghost-container, so:

docker stop ghost-container
docker rm ghost-container

Now we have no Ghost container at all! Fortunately, the Ghost image is already at the latest so we can simply set up another Ghost container with the following:

docker run --name ghost-container -d --expose 2368 -e VIRTUAL_HOST=www.bauerspace.com -e NODE_ENV=production -v /path/to/your/ghost/data:/var/lib/ghost ghost

You'll probably want to change the --name, VIRTUAL_HOST, and /path/to/your/ghost/data as needed.

There was only one significant difference for me when it came to the above command. Previously, when using -e NODE_ENV=production it was necessary to include -v /path/to/your/ghost/data:/usr/src/ghost/content as well. With 0.9.x, this appears to make the container angry. As in, it does not work. A quick look around the Internet revealed this comment that solved everything. Long story short, it is necessary to append the following to the production section of config.json:

paths: {
    contentPath: path.join(process.env.GHOST_CONTENT, '/')
}

With any luck, that should be everything to get the new Ghost container up and running.

Data-tize Me, Captain!

There will likely be no data and just an empty Ghost instance. Spooky, right?

Head to the appropriate admin url (e.g., localhost:2368/ghost) and create an account. Once inside the admin area, simply go to Labs and import the data you saved previously. You will be logged out and the blog will be populated with data once more.

In the event things are not going as desired, you should be able to set up a Ghost container of the version you were previously using with all that wisely backed up data.

Thats all there is to this - hope it went well!


Photo by Samuel Zeller / Unsplash