There are enough resources out there that show you how to install Ghost on these tiny machines. I used this post:

Install Ghost on Raspberry Pi 4 running Raspbian Buster
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! Learn how to install the latest version on Ghost on Raspbian Buster with Ghost Pi!

Although my Ghost installation is running a Pi 2, the instructions still apply. But you have to be very patient... Or do as I did and change the way Let's Encrypt is setup by ghost-cli.

What happened?

Running the ghost-cli installer is a breeze, just answer some questions and a few minutes later Ghost is up and running behind an Nginx server and a connected and populated MySQL database.

What puzzled me was the time it took to setup SSL through Let's Encrypt. The issue was the way ghost-cli sets up Nginx to use SSL. Generating the dhparam file took way too long for my comfort. Googling, I found out that this is indeed a CPU bound task according to this post:

Diffie Hellman parameters still calculating after 24 hours
I have a fresh install of Arch Linux on a RaspberryPi model B. I’m setting up OpenVPN and using easy-rsa with OpenSSL 1.0.2d to generate initial keys and certificates. All went fine until I ran ./b...

The answer suggest to use the -dsaparam, which

... is considerably faster because it does not need to nest the primality tests, and thus only thousands, not millions, of candidates will be generated and tested.

As far as academics know, DSA-like parameters for DH are equally secure; there is no actual advantage to using "strong primes" (the terminology is traditional and does not actually imply some extra strength).

'Fixing' Ghost

For ghost-cli, take these steps:

  • Edit /usr/lib/node_modules/ghost-cli/extensions/nginx/index.js
  • Find the line saying openssl dhparam -out (around line 190)
  • Add -dsaparam just before -out

On my installation, the code now looks like this:

        }, {
            title: 'Generating Encryption Key (may take a few minutes)',
            skip: () => fs.existsSync(dhparamFile),
            task: () => this.ui.sudo(`openssl dhparam -dsaparam -out ${dhparamFile} 2048`)
                .catch(error => Promise.reject(new ProcessError(error)))
        }, {

Undoing the failed SSL setup

If you found my post too late, you might encounter this message:

$ ghost setup ssl
SSL has already been set up, skipping
ℹ Setting up SSL [skipped]

But Nginx won't start. This is because you stopped the openssl command (Ctrl-C?) before it could write to dhparam.pem and this file is now empty.

To fix this, undo the SSL setup by hand. Remove these files:

  • /etc/nginx/snippets/dhparam.pem
  • /etc/nginx/sites-enabled/www.sanderverbruggen.com-ssl.conf
  • /etc/nginx/sites-available/www.sanderverbruggen.com-ssl.conf

Substitute your own sitename of course...

Restarting the SSL setup

Now go back to the installation dir for your Ghost site and run the SSL setup.

$ ghost setup ssl

Things should now run smoothly and quickly!