This blog post walks you through the steps necessary for migrating Ghost applications from OpenShift v2 over to OpenShift v3. The process describes the migration of:

  • the application logic
  • the database
  • the static assets

Getting the Application Source Code from OpenShift v2

Before we start deploying the application on OpenShift v3, we need to fetch the data from OpenShift v2. To do that we will need the rhc client tool. As this tutorial is intended for v2 users, I expect you to already have the tool installed. However, in case you do not, these are the steps I had to take to install rhc:

gem install rhc
gem uninstall rbnacl -v 5.0.0
gem install rbnacl -v 4.0.2
gem install rbnacl-libsodium
gem install bcrypt_pbkdf

You will also need the OpenShift v3 command line tool, please install it now. For the rest of the tutorial I will work on the assumption your applications on both OpenShift v2 and v3 are called ghost.

The first step is to download the source code of the application:

rhc git-clone ghost

Currently there is a directory called ghost in the current working directory that contains the full source code of your application.The next step is to download the other data you had in your ghost installation, that is, the images and uploaded files.

Now find the username and hostname for your application. Assuming your application is called ‘wordpress’, issue the following command:

rhc app show ghost

You will see the following line in the output:

SSH:        51af743a4382ec4fc90000ca@ghost-mynamespace.rhcloud.com

Now that we know the username and hostname, issue the following command using the correct information for your deployment:

scp -r 51af743a4382ec4fc90000ca@wordpress-mynamespace.rhcloud.com:~/app-root/data/content/data .
scp -r 51af743a4382ec4fc90000ca@wordpress-mynamespace.rhcloud.com:~/app-root/data/content/images .

Now there should be three directories in your working directory: ghost, images, and data.

Cleaning and Uploading the Source Code

Enter the directory to work with the Ghost application:

cd ghost

OpenShift v3 does not have the concept of action_hooks nor scheduled jobs as part of the application source code, so there is no need for the .openshift directory, thus you can safely remove it. (In case you have been actively using features from this directory, feel free to keep it or make sure you have migrated all the behaviour to OpenShift v3 as well).

rm -rf .openshift

And you need to commit the changes to Git as well:

git add . && git commit -m “moving out of v2”

OpenShift v3 does not have Git hosting by itself, but integrates with any hosting platform of your choice; you can safely use Gitlab, Github, or for example, Bitbucket. The only requirement is that you have the source code hosted somewhere, where OpenShift can access it and clone it locally to build the container image for you.

git remote remove origin
git remote add origin <url>
git push -u origin master

First remove the origin remote as it points to the OpenShift v2 and then add a new origin pointing to your Git repository and finally push the source code.

Deploying the New Database

Before we start migrating the data, we need to deploy MySQL. It’s more convenient to do that using the command line tool, as we will need to capture some of the information printed out. Run this command:

oc new-app mysql-persistent

and save the output to some text file for later usage. Also, now is a good time to migrate the MySQL data. For those steps, please follow this guide and then come back here.

Deploying Ghost to OpenShift v3

Again, it’s easier to deploy the application using the command line tool:

oc new-app nodejs~<git hosting url> --name=ghost -e OPENSHIFT_APP_DNS=”” -e OPENSHIFT_MYSQL_DB_HOST=”mysql” -e OPENSHIFT_MYSQL_DB_PORT=”3306” -e OPENSHIFT_APP_NAME=”sampledb” -e OPENSHIFT_NODEJS_IP=”0.0.0.0” -e OPENSHIFT_NODEJS_PORT=”8080” -e OPENSHIFT_MYSQL_DB_USERNAME=”<MySQL Connection Username>” -e OPENSHIFT_MYSQL_DB_PASSWORD=”<MySQL Connection Password>”

The git hosting URL, username, and password was printed out in the previous step. Simply copy the two values instead of the placeholders, removing the brackets (<>) as well.

Once the process is finished, you will have Ghost running and connected to the database that contains the data migrated from OpenShift v2; however the application will not start yet.

Exposing the Application to the Internet

By default, OpenShift no longer exposes applications to the public network, but the user can choose which components should be internal and what components should be accessible from outside.

First we expose the service of our application:

oc expose svc ghost

Then inspect the generated route:

oc get route ghost

And update the deployment configuration with this information:

oc set env dc ghost OPENSHIFT_APP_DNS="<from previous command below HOST/PORT>"

And that’s it, your Ghost instance is running. However, you still have one last step, we have to import the uploaded data and images.

Change Deployment Strategy

By default OpenShift works with the “Rolling” deployment strategy, which ensures that there is no downtime to your application during deployments. However, it does not work correctly with persistent volumes, unless you have something like Gluster, which is not provided on OpenShift. And because Ghost needs persistent storage, we need to switch from “Rolling” to “Recreate”:

oc patch dc ghost -p '{"spec":{"strategy":{"type":"Recreate"}}}'

Once finished, any new deployment will first stop the application and then start the new version, thus there is no problem with concurrent access to the persistent disk from multiple instances or nodes.

Uploading Static Content

Our application needs persistent volumes for storing the static content, as those will ensure that the data is not lost during redeployments of the app. To do this, first create and attach the persistent volumes to our application:

oc set volume dc ghost-migration --add --name=images --claim-name=ghost-images -t pvc --claim-size=1Gi --mount-path=/opt/app-root/src/content

oc set volume dc ghost-migration --add --name=data --claim-name=ghost-daa -t pvc --claim-size=1Gi --mount-path=/opt/app-root/src/content/data

Finally we will upload all the static data we downloaded before from OpenShift v2. First look up the name of your pod:

oc get pods

Find the ‘Running’ pod starting with ghost and the name will end with some hash, for example:

ghost-9-tbw6k   1/1       Running     0          3m

Copy the pod name, in my case it was ghost-9-tbw6k, and run these two commands to sync the data over to OpenShift v3:

oc rsync images ghost-9-tbw6k:/opt/app-root/src/content
oc rsync data ghost-9-tbw6k:/opt/app-root/src/content

Conclusion

This blog post walked you through the process of migrating Ghost applications from OpenShift v2 over to OpenShift v3, including the data in the database and static assets on the disk.

One important thing to note here is: The usage of persistent volumes means, your application can not scale to more than one instance and it can not use the Rolling strategy!