Install Ghost v1.x on Heroku

Heroku has always been my favorite platform for hosting prototypes and demo apps. I have 2 Ghost sites hosted on Heroku for display 2 of my Ghost themes. I haven’t touched either of them since 2016 and they have been running without a problem. However, as I checked out what has changed to Ghost since 2016, I found out the core code changes make it harder to deploy new versions (v1.0 and above) to Heroku. Fortunately there is a solution, and here is how it works.

Note that this post is very specific to my use case: upgrade a demo site from Ghost v0.11.x to v1.22.x. The solution will make some small changes to Ghost core code, which makes future upgrades harder to maintain. I am OK with it because I am not going to frequently update these demo sites. But if you are deploying serious projects, or a frequently updated blog, my solution is not great.

Before Getting Started

Make sure you have git, Node.js and npm.

Install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli

Download Ghost

Download the .zip version of Ghost source code from https://ghost.org/developers/. Unzip it to a folder.

Initialize Git Project

I highly recommend you not do the git push --force. I did because I really don’t care.

git init
git add -A
git commit -m "init project"
git remote add origin <your-heroku-git-url>
git push --force --set-upstream origin master

Set up MySQL

Ghost v1+ only officially supports MySQL. So you need to deploy a MySQL add-on. Either do it via Heroku console or using this command:

heroku addons:create cleardb:ignite

Find database connection credentials by going to Settings tab and look for the CLEARDB_DATABASE_URL config variable, or using this command:

heroku config:get CLEARDB_DATABASE_URL

It should look like mysql://<db-user>:<db-password>@<db-host>/<db-ame>;

Set some more config variables:

heroku config:set \ 
database__connection__user=<db-user> \ 
database__connection__password=<db-password> \ 
database__connection__host=<db-host> \
database__connection__database=<db-name> \
database__pool__max=2

These config variables will make sure the database connection credentials be picked up by Ghost.

Run the following command to initialize the database. You can also run it from Heroku console. Click the ‘More’ dropdown and choose Run Console, type in bash and hit enter. You will be able to run shell commands in your dyno.

heroku run "knex-migrator init"

It will fail, at least it did it to me. The error will look like Error: Tarn: opt.max must be an integer > 0.

The solution is to change a core file core/server/config/index.js, look for this snippet:

nconf.env({
  separator: '__'
});

Change it to:

nconf.env({
  separator: '__',
  parseValues: true
});

Thanks to this Github issue: https://github.com/tgriesser/knex/issues/2570

Configurate Ghost

heroku config:set server__host=0.0.0.0
heroku config:set url=https://yabu.rakugaki.me

Add the following to core/server/config/index.js so that Ghost can pick up the $PORT env variable.

nconf.set('server', {
  port: process.env.PORT
});

Now do another deployment and the Ghost site should be running on Heroku.