How to deploy Ghost v1.x on Heroku for free
Ghost is a very popular blog platform that supports Markdown. It is very powerful and easy to use. This article will give you the keys to deploy it quickly and for free on Heroku.
1. Create a new application on Heroku
The first step is signing up for Heroku. If you are familiar with Heroku, just go to the next step, else you can follow this quick start guide.
2. Downloading Ghost
As I am writing this article, the last version of Ghost is v1.7.1.
- Head to the website and download the last version.
- Unzip the Ghost version in the directory of your choice:
$ unzip ~/Downloads/Ghost-1.7.1.zip -d ~/projects/my-blog
$ cd ~/projects/my-blog
3. Create a Heroku application
Since Heroku deployment is based on git, we have to create a git repository to host Ghost source code.
To initialize a new git repository, use these commands in your project directory:
$ git init
$ git add -A
$ git commit -m 'Initialize repository'
Next we will set-up the application using heroku-cli. If you do not have heroku-cli installed on your machine, follow this guide: https://devcenter.heroku.com/articles/heroku-cli.
First we create an application, replace “my-blog” by the name of your blog.
$ heroku create my-blogCreating ⬢ my-blog... done
https://my-blog.herokuapp.com/ | https://git.heroku.com/my-blog.git
We can now deploy our blog on Heroku.
$ git push heroku masterReleased v13
https://my-blog.herokuapp.com/ deployed to Heroku
Even if the deployment was successful, your blog is not functional yet. A major element is still missing: the database.
4. Install mySQL
Ghost database is mySQL, to make it work on Heroku, you have to choose a mySQL provider. I am not an expert but ClearDB sounds like a good choice. Let’s add the mySQL add-on to our application:
$ heroku addons:create cleardb:igniteCreating cleardb:ignite on ⬢ my-blog... free
Created cleardb-aerodynamic-72322 as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation
The add-on is now installed but it is still not used by our Ghost application. We must set up database credentials using heroku config
:
First, get credentials of your database:
$ heroku config:get CLEARDB_DATABASE_URLmysql://b74638b58e8fff:dc944939@us-cdbr-iron-east-05.cleardb.net/heroku_6a6045b8e83395b?reconnect=true
You should get something like that, the format of the url is : “mysql://user:password@host/database?reconnect=true”
Second, using heroku config:set
, configure each part of the url:
$ heroku config:set \
database__connection__user=b74638b58e8fff \
database__connection__password=dc944939 \
database__connection__host=us-cdbr-iron-east-05.cleardb.net \
database__connection__database=heroku_6a6045b8e83395bSetting database__connection__user, database__connection__password, database__connection__host, database__connection__database and restarting ⬢ my-blog... done, v4
database__connection__database: heroku_6a6045b8e83395b
database__connection__host: us-cdbr-iron-east-05.cleardb.net
database__connection__password: dc944939
database__connection__user: b74638b58e8fff
Unfortunately the free tier of ClearDB does not allow us a lot of connections. We can set the connections to 2 max, enough for a small website:
$ heroku config:set database__pool__max=2
You database connection is now configured, but database is still empty. We must initialize it using heroku run
.
$ heroku run "knex-migrator init"Running knex-migrator init on ⬢ my-blog... up, run.3926 (Free)
[2017-08-28 13:47:59] INFO Creating table: posts
[2017-08-28 13:47:59] INFO Creating table: users
[2017-08-28 13:47:59] INFO Creating table: roles
[2017-08-28 13:47:59] INFO Creating table: roles_users
[2017-08-28 13:47:59] INFO Creating table: permissions
[2017-08-28 13:47:59] INFO Creating table: permissions_users
[2017-08-28 13:47:59] INFO Creating table: permissions_roles
[2017-08-28 13:47:59] INFO Creating table: permissions_apps
[2017-08-28 13:48:00] INFO Creating table: settings
[2017-08-28 13:48:00] INFO Creating table: tags
[2017-08-28 13:48:00] INFO Creating table: posts_tags
[2017-08-28 13:48:00] INFO Creating table: apps
[2017-08-28 13:48:00] INFO Creating table: app_settings
[2017-08-28 13:48:00] INFO Creating table: app_fields
[2017-08-28 13:48:00] INFO Creating table: clients
[2017-08-28 13:48:00] INFO Creating table: client_trusted_domains
[2017-08-28 13:48:00] INFO Creating table: accesstokens
[2017-08-28 13:48:00] INFO Creating table: refreshtokens
[2017-08-28 13:48:00] INFO Creating table: subscribers
[2017-08-28 13:48:00] INFO Creating table: invites
[2017-08-28 13:48:01] INFO Creating table: brute
[2017-08-28 13:48:01] INFO Model: Post
[2017-08-28 13:48:01] INFO Model: Tag
[2017-08-28 13:48:01] INFO Model: Client
[2017-08-28 13:48:02] INFO Model: Role
[2017-08-28 13:48:02] INFO Model: Permission
[2017-08-28 13:48:03] INFO Model: User
[2017-08-28 13:48:03] INFO Relation: Role to Permission
[2017-08-28 13:48:04] INFO Relation: Post to Tag
[2017-08-28 13:48:04] INFO Relation: User to Role
[2017-08-28 13:48:04] INFO Finished database init!
If you see “Finished database init!” it is good. Do not panic if command is not responding. Just terminate it manually (control + C).
5. Configure server
We have to change the host binding, the default is “127.0.0.1” but using Heroku we have to set it to “0.0.0.0”.
$ heroku config:set server__host=0.0.0.0
We can also set up our blog url:
$ heroku config:set url=https://my-blog.herokuapp.com
On Heroku, the web application port is dynamic and provided in “PORT” environment variable by Heroku.
In Ghost, we have to set up the application port using “server__port” environment variable.
To make an alias between “PORT” and “server__port” we create a “.profile” at the root of our application.
$ echo "export server__port=\$PORT npm start" > .profile
$ git add .profile
$ git commit -m 'Add .profile'
$ git push heroku master
Your blog is now ready, enjoy!