Install the latest version of Ghost on Raspberry Pi 4

The Raspberry Pi 4 was launched on Monday 24 June 2019, and with the massive boost in performance, it quickly became the hot topic and began to sell out with all the major Raspberry Pi resellers.

With vastly superior specifications, the Pi 4 makes an ideal choice for a web server and combining that with the speed and responsiveness Ghost offers, it is a match made in Raspberry Pi heaven!

Thankfully, the latest version of Ghost (2.25.3 at the time of writing) can be installed on the new Raspberry Pi 4 and Ghost Pi has the details below.

Prepare your Raspberry Pi 4

Before installing the latest version of Ghost (2.25.3 at the time of writing), you should make sure you have updated Raspbian to ensure you are running the latest software. This is just good practice.

boo@ghost-pi ~ $ sudo apt-get update && sudo apt-get dist-upgrade -y

Depending on when you last did this, it could take a while so be patient. Once done, it is worth updating the firmware on your Raspberry Pi too:

boo@ghost-pi ~ $ sudo rpi-update

To complete the update process, reboot your Pi with sudo reboot.

RAID-1 for data redundancy on Raspbian Buster?

If you want to provide some data redundancy on your Ghost blog, then you should consider setting up a RAID-1 array over 2 USB flash drives. Ghost Pi's previous guide can show you what to do here, but if you do not want any fall-back options on your Ghost blog, then continue reading.

Install the latest version of Ghost on Raspbian Buster

Now that your Raspberry Pi is up-to-date and you have configured a RAID-1 array for data redundancy, you can start the installation process for Ghost 2.0.0 and above.

Required packages for Ghost on Raspbian Buster

It is recommended that you install the following packages on your Raspberry Pi to get the most out of your Ghost blog. Run the following commands in the terminal:

boo@ghost-pi ~ $ sudo apt-get install ufw nginx mariadb-server -y

This will install UncomplicatedFirewall (ufw), NGINX and MariaDB. Next we'll need to configure those packages:

UncomplicatedFirewall configuration

With any firewall, we need to ensure that certain rules are in place. The following commands should take care of that:

boo@ghost-pi ~ $ sudo ufw allow ssh && sudo ufw allow http && sudo ufw allow https && sudo ufw allow 'Nginx Full'

This will allow SSH, HTTP, HTTPS and all NGINX required actions within the firewall. Now enable the firewall:

boo@ghost-pi ~ $ sudo ufw enable

MariaDB configuration

Ghost relies on a database to run, so we'll configure MariaDB as follows:

boo@ghost-pi ~ $ sudo mysql_secure_installation

You'll be asked for a root password, but as this is the first time you've started this process, you won't have one. Just press Enter and continue. You can now set a password for the root user, so make it strong and keep it safe as you'll need it later!

Next, you'll be prompted to answer 4 questions. Answer as follows:

  1. Remove anonymous users? - Yes
  2. Disallow root login remotely? - No
  3. Remove test database and access to it? - Yes
  4. Reload privilege tables now? - Yes

You should now find yourself back at the terminal. Good! We can now configure the database:

boo@ghost-pi ~ $ sudo mysql -u root -p

This will launch MariaDB as the root user and will ask you to input your password. Do that and then run the following commands - being careful to include the trailing ; at the end of each command:

MariaDB [(none)]> USE mysql;
MariaDB [(mysql)]> UPDATE user SET plugin='mysql_native_password' WHERE User='root';
MariaDB [(mysql)]> FLUSH PRIVILEGES;
MariaDB [(mysql)]> exit;

Configure NGINX

This step may not be essential, but others have reported some issues with server_names_hash_bucket_size, so to resolve that edit the NGINX configuration file and uncomment the relevant line:

boo@ghost-pi ~ $ sudo nano /etc/nginx/nginx.conf

The part you need to uncomment is usually on line 24 of the above file and looks like this:

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

The second-from-last line has already been uncommented (removed the #) so just exit (CTRL+X) and save (Y) to make the changes stick. Test the NGINX configuration and restart the service now:

boo@ghost-pi ~ $ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
boo@ghost-pi ~ $ sudo systemctl restart nginx

Install Node.js on your Raspberry Pi

UPDATE: Ghost now recommends installing Node.js 10.x to maintain LTS!

Installation of Node.js on Raspberry Pi is thankfully quite straight forward, unless you are using an old Model B Pi as the process below only supports ARMv7 CPU architectures (i.e. Raspberry Pi 2, 3, 3+ and now 4):

boo@ghost-pi ~ $ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash
boo@ghost-pi ~ $ sudo apt-get install -y nodejs

This will install the latest version of Node.js 10.x, which is supported by Ghost. We can now continue installing Ghost, so keep it up!

Create your Ghost installation folder

If you have created a RAID-1 array to provide you with some data redundancy, then the location is likely to be different to those of you who are not using RAID-1. We'll show two options below:

Install Ghost with RAID-1 array on Raspbian Buster

Assuming you've followed our guide on setting RAID-1 up on Raspbian Buster, this is where you can create your Ghost installation directory:

boo@ghost-pi ~ $ sudo mkdir -p /mnt/raid1/nginx/ghost
boo@ghost-pi ~ $ sudo chown [user]:[user] /mnt/raid1/nginx/ghost

Install Ghost without RAID-1 array on Raspbian Buster

Again, this assumes you have not altered the default location for your setup:

boo@ghost-pi ~ $ sudo mkdir -p /var/www/ghost
boo@ghost-pi ~ $ sudo chown [user]:[user] /var/www/ghost

You will need to substitute the [user]:[user] with your current user, which is normally pi:pi unless you have created a new user yourself. Now you can install the Ghost CLI tool.

Install Ghost CLI on Raspberry Pi

Node.js is required before the Ghost CLI tool can be installed, so assuming you are following this guide in sequence, you can install the CLI tool by running:

boo@ghost-pi ~ $ sudo npm i -g ghost-cli@latest

This process can take several minutes, so be patient and let the task complete. Once done, you can finally install the latest version of Ghost on your Raspberry Pi 4 running Raspbian Buster!

Install the latest version of Ghost on Raspberry Pi 4

To install Ghost you need to run the following command from within the Ghost installation directory you created earlier. This will be one of two depending on if you have the RAID-1 array or not:

With RAID-1 on Raspbian Buster

boo@ghost-pi ~ $ cd /mnt/raid1/nginx/ghost

Without RAID-1 on Raspbian Buster

boo@ghost-pi ~ $ cd /var/www/ghost

Ghost install

Once in your Ghost install directory, finally run:

boo@ghost-pi ~ $ ghost install

And then follow the prompts during the process to get your Ghost blog installed and up and running!

Tweak systemd if installing on RAID-1

Due to how Raspbian Buster loads RAID-1 etc., your Ghost blog is unlikely to start on boot unless you tweak the service file. The Ghost CLI tool creates a soft symlink, rather than copying the file directly to the required location, and as such, this does not always load on boot.

There's an easy fix:

boo@ghost-pi ~ $ sudo rm /lib/systemd/system/ghost_nameofyourghostblog.service
boo@ghost-pi ~ $ sudo cp /mnt/raid1/nginx/ghost/system/files/ghost_nameofyourghostblog.service /lib/systemd/system/

The two commands above deleted the soft symlink, then copies the file (located in your Ghost install directory within /system/files to the same location. Now your blog should start automatically on reboot.

Updating Ghost breaks systemd on RAID-1

Due to how the Ghost CLI tool works, if you update your Ghost blog later on, then chances are the systemd service file will be reset to the default (soft symlink), so just re-run the commands above to rectify this until Ghost fix it in the future.