Ghost

Ghost is a open source blogging platform written in JavaScript and distributed under the MIT License, designed to simplify the process of online publishing for individual bloggers as well as online publications.

The concept of the Ghost platform was first floated publicly in November 2012 in a blog post by project founder John O’Nolan, which generated enough response to justify coding a prototype version with collaborator Hannah Wolfe.


Note

For this guide you should be familiar with the basic concepts of

Prerequisites

We’re using Node.js in the stable version 8:

[isabell@stardust ~]$ uberspace tools version show node
Using 'Node.js' version: '8'
[isabell@stardust ~]$

You’ll need your MySQL credentials. Get them with my_print_defaults:

[isabell@stardust ~]$ my_print_defaults client
--default-character-set=utf8mb4
--user=isabell
--password=MySuperSecretPassword
[isabell@stardust ~]$

Your blog URL needs to be setup:

[isabell@stardust ~]$ uberspace web domain list
isabell.uber.space
[isabell@stardust ~]$

Installation

Install ghost-cli and knex-migrator

Use npm to install ghost-cli and knex-migrator globally:

[isabell@stardust ~]$ npm i -g ghost-cli knex-migrator
[...]
+ ghost-cli@1.9.1
+ knex-migrator@3.2.3
added 690 packages in 31.543s
[isabell@stardust ~]$

Install Ghost

Create a ghost directory in your home, cd to it and then run the installer. Since the installer expects to be run with root privileges, we need to adjust some settings:

  • --no-stack: Disables the system stack check during setup. Since we’re a shared hosting provider, the stack is maintained by us.
  • --no-setup-linux-user: Skips creating a linux user. You can’t do that without root privileges.
  • --no-setup-systemd: Skips creation of a systemd unit file. We’ll use supervisord later instead.
  • --no-setup-nginx: Skips webserver configuration. We’ll use a htaccess file for apache later instead.
  • --no-setup-mysql: Skips setup of MySQL. You can’t do that without root privileges.

You will need to enter the following information:

  • your blog URL: The URL for your blog. Since we don’t allow HTTP, use HTTPS. For example: https://isabell.uber.space
  • your MySQL hostname, username and password: the hostname is localhost and you should know your MySQL credentials by now. If you don’t, start reading again at the top.
  • your Ghost database name: we suggest you use a additional database. For example: isabell_ghost
  • Do you want to start Ghost?: Answer No.
[isabell@stardust ~]$ mkdir ~/ghost
[isabell@stardust ~]$ cd ~/ghost
[isabell@stardust ghost]$ ghost install --no-stack --no-setup-linux-user --no-setup-systemd --no-setup-nginx --no-setup-mysql
✔ Checking system Node.js version
✔ Checking current folder permissions
ℹ Checking operating system compatibility [skipped]
✔ Checking for a MySQL installation
✔ Checking for latest Ghost version
✔ Setting up install directory
✔ Downloading and installing Ghost v2.0.0
✔ Finishing install process
? Enter your blog URL: https://isabell.uber.space
? Enter your MySQL hostname: localhost
? Enter your MySQL username: isabell
? Enter your MySQL password: [hidden]
? Enter your Ghost database name: isabell_ghost
✔ Configuring Ghost
✔ Setting up instance
ℹ Setting up "ghost" mysql user [skipped]
ℹ Setting up Nginx [skipped]
Task ssl depends on the 'nginx' stage, which was skipped.
ℹ Setting up SSL [skipped]
ℹ Setting up Systemd [skipped]
✔ Running database migrations
? Do you want to start Ghost? No
[isabell@stardust ghost]$

Configuration

Configure port

Since Node.js applications use their own webserver, you need to find a free port and bind your application to it.

[isabell@stardust ~]$ FREEPORT=$(( $RANDOM % 4535 + 61000 )); ss -ln src :$FREEPORT | grep $FREEPORT && echo "try again" || echo $FREEPORT
9000
[isabell@stardust ~]$

Write the port down. In our example it is 9000. In reality you’ll get a free port between 61000 and 65535.

Change the configuration

You need to adjust your ~/ghost/config.production.json with the new port. Find the following code block and change port 2369 to your own port:

"server": {
  "port": 2369,
  "host": "127.0.0.1"
},

In our example this would be:

"server": {
  "port": 9000,
  "host": "127.0.0.1"
},

Setup .htaccess

Create a ~/html/.htaccess file with the following content:

Warning

Replace <yourport> with your port!

DirectoryIndex disabled

RewriteEngine On
RewriteRule ^(.*) http://localhost:<yourport>/$1 [P]

In our example this would be:

DirectoryIndex disabled

RewriteEngine On
RewriteRule ^(.*) http://localhost:9000/$1 [P]

Setup daemon

Create ~/etc/services.d/ghost.ini with the following content:

Warning

Replace <username> with your username!

[program:ghost]
directory=/home/<username>/ghost
command=env NODE_ENV=production /bin/node current/index.js

In our example this would be:

[program:ghost]
directory=/home/isabell/ghost
command=env NODE_ENV=production /bin/node current/index.js

Tell supervisord to refresh its configuration and start the service:

[isabell@stardust ghost]$ supervisorctl reread
ghost: available
[isabell@stardust ghost]$ supervisorctl update
ghost: added process group
[isabell@stardust ~]$ supervisorctl status
ghost                            RUNNING   pid 26020, uptime 0:03:14
[isabell@stardust ~]$

If it’s not in state RUNNING, check your configuration.

Finishing installation

Point your browser to your blog URL and create a user account.

Updates

Note

Check the update feed regularly to stay informed about the newest version.

Download and unzip new version

Check Ghost’s releases for the latest version and copy the link to the .zip archive. In this example the version is 23.42.1, which of course does not exist. Change the version to the latest one in the highlighted lines.

[isabell@stardust ~]$ cd ~/ghost/versions/
[isabell@stardust versions]$ wget https://github.com/TryGhost/Ghost/releases/download/23.42.1/Ghost-23.42.1.zip
[isabell@stardust versions]$ unzip Ghost-23.42.1.zip -d 23.42.1
Archive:  Ghost-23.42.1.zip
[isabell@stardust versions]$

Install the required node modules

[isabell@stardust ~]$ cd ~/ghost/versions/23.42.1/content
[isabell@stardust content]$ npm install --production
[...]
added 91 packages, removed 134 packages and updated 544 packages in 27.303s
[isabell@stardust content]$

Migrate your database

[isabell@stardust ~]$ cd ~/ghost
[isabell@stardust ~]$ NODE_ENV=production knex-migrator migrate --init --mgpath ./versions/23.42.1/
[2018-08-22 14:18:21] INFO Creating database backup
[…]
[2018-08-22 16:18:23] INFO Finished database migration!