Ghost on Pi

Ghost is an open-source blogging platform written in Node.js that offers both self-hosted and fully hosted services.

In this guide, we are going to self-host Ghost on a Raspberry Pi. This will take you through the steps of setting up a self-hosted Ghost production environment.

I am working on this setup with a clean install of Raspbian in a headless setup. You can learn how to enable SSH here.

Mac and Linux users can SSH directly into the Raspberry Pi via the terminal. If you are a Windows user, you will need to use PuTTY.

ssh pi@the-ip-address-of-the-pi

The default username and password for a fresh Raspbian install is:

  • User: pi
  • Password: raspberry

Installing Node.js & Dependencies

First, download Node.js (NPM ships with it):

wget http://node-arm.herokuapp.com/node_latest_armhf.deb

Install Node.js (required by Ghost):

sudo dpkg -i node_latest_armhf.deb

Install SQLite (the database used by Ghost):

sudo apt-get install sqlite3

Install NGINX (used as a reverse proxy for Ghost):

sudo apt-get install nginx-full

Install Supervisor (used to keep Ghost running in the background):

sudo apt-get install supervisor

Ghost Setup

Download the latest version of Ghost:

wget https://ghost.org/zip/ghost-latest.zip

Unzip the downloaded folder:

unzip ghost-latest.zip -d Ghost

Set Ghost/ as the current directory:

cd Ghost/

Install the dependencies used by Ghost via NPM:

npm install --production

Run the command below to ensure everything works properly:

npm start --production

Running Ghost as a Service

Now it's time to turn Ghost into a background service.

Create a ghost.conf file for Supervisor to manage Ghost:

sudo touch /etc/supervisor/conf.d/ghost.conf

Open the file in your preferred text editor (like nano):

sudo nano /etc/supervisor/conf.d/ghost.conf

Add these lines to the ghost.conf file:

[program:ghost]
command = npm start --production
directory = /home/pi/Ghost/
user = pi
autostart = true
autorestart = true
stdout_logfile = /var/log/supervisor/ghost.log
stderr_logfile = /var/log/supervisor/ghost_err.log
environment = NODE_ENV="production"

Save and exit the file (in nano, press CTRL + X, then Y, and Enter).

Start Supervisor, if it did not start automatically after installation:

sudo service supervisor start

Set Supervisor to run automatically on startup:

sudo update-rc.d supervisor defaults

Start the Ghost service we just created:

sudo supervisorctl start ghost

Ghost is now running in production on port 2368.

Reverse Proxying Ghost with NGINX

Open your NGINX default configuration file:

sudo nano /etc/nginx/sites-enabled/default

Replace its contents with the following lines:

server {
    listen 80;
    server_name yourdomain.com; # Change this to your hostname

    location / {
        proxy_pass http://127.0.0.1:2368;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Save and exit the file, then restart NGINX:

sudo service nginx restart

Now, visit your Raspberry Pi's IP address in your web browser. You will be presented with a beautiful setup screen.

You can edit the Ghost hostname and other settings by modifying the config.js file stored inside your Ghost directory. Services like DynDNS can be used to manage your hostname if you want your Ghost blog to be public and use a domain name instead of an IP address.

If you have any questions or run into problems, leave a comment below!

I'm Feeling Lucky
Darryl Dias

Written by Darryl Dias

The AI guy and founder of Caprycon, building AI-powered tools, exploring emerging technologies, and sharing insights from the world of artificial intelligence