Little T in the Cog linux

Installing Ghost on Raspbian

2016-08-08

I recently had a need to install Ghost for a project I'm starting. Ghost is a Node.js app that is a very popular blogging platform. It needs Node.js installed on the server it is running on and can also use a MySQL database backend for storing content. It has excellent documentation but I had to do a few things differently to get it up and running on Raspbian/ARM so I'll document it all here.

The first thing to do is install Node.js. You can use the version shipping with Raspbian as it is supported (currently version 0.10.x, installable via apt-get), but the Ghost folks recommend the LTS version 4 at time of writing this which unfortunately doesn't appear to be in any repos I can find for ARM. Luckily you can download the binaries directly from the Node.js project. You want to install the latest version of 4.x, in my case at the time of writing 4.4.7. the release you want is armv7l for Raspberry Pi 2/3, or if you're still running an older version 1 Pi you'll want to download armv6l. Once you've downloaded it unzip it and copy the binaries and libraries into place on the system somewhere in your path (in my case I copied them to /usr/local/).

curl -O http://nodejs.org/dist/latest-v4.x/node-v4.4.7-linux-armv7l.tar.gz
tar -zxvf node-v4.4.7-linux-armv7l.tar.gz
sudo rsync -av node-v4.4.7-linux-armv7l/bin/ /usr/local/bin/
sudo rsync -av node-v4.4.7-linux-armv7l/include/ /usr/local/include/
sudo rsync -av node-v4.4.7-linux-armv7l/lib/ /usr/local/lib/
sudo rsync -av node-v4.4.7-linux-armv7l/share/ /usr/local/share/

now you've got everything you need to run Ghost (and other Node.js apps) copied into the correct place.

The next step is to install Ghost. For this we create a new user for the app to run as ("ghost"), download and unzip the app, copy it into /var/www/ and run the setup.

sudo useradd -r ghost -U
mkdir ghost && cd ghost
curl -O -L https://ghost.org/zip/ghost-latest.zip
unzip ghost-latest.zip
cd ../ && mv ghost /var/www/
cd /var/www/ghost
sudo chown -R ghost: /var/www/ghost
sudo -u ghost npm install --production
At this point ghost is set up ready to run, though the config file needs a tweak or two. Follow the guide to configure it how you like it (in my case I use MySQL for my blog so all I had to do was add that section, give the blog a URL and add my email address). Once you're happy start the blog by hand to test it:
npm start --production
At this point it should be running on port 2368 on localhost (assuming you left it at the default), so to go further you'll need to configure a reverse proxy to connect to the app. I'm running the excellent Hiawatha webserver so I created a virtualhost like this:
VirtualHost {
	Hostname = myblog.co.nz
	AccessLogfile = /var/log/hiawatha/myblog-access.log
	ErrorLogfile = /var/log/hiawatha/myblog-error.log
	WebsiteRoot = /var/www/ghost
	ReverseProxy .* http://127.0.0.1:2368/
}
If you're running apache then make a vhost somethihng like this:
<VirtualHost *:80>
    ServerName myblog.co.nz
    ServerAlias www.myblog.co.nz
    ProxyPass / http://127.0.0.1:2368/ 
    ProxyPassReverse / http:/127.0.0.1:2368/     
</VirtualHost>
And nginx might look something like:
location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HOST $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://127.0.0.1:2368;
        proxy_redirect off;
    }
Whatever method you use, at this point you should be able to browse to your blog. If all is well the final step is to create a systemd startup script.
cat <<EOF > /etc/systemd/system/ghost.service
[Unit]
Description=Ghost blog
After=network.target

[Service]
Type=simple
PIDFile=/run/ghost.pid
WorkingDirectory=/var/www/ghost
User=ghost
Group=ghost
ExecStart=/usr/local/bin/npm start --production
ExecStop=/usr/local/bin/npm stop --production
StandardOutput=null
StandardError=null
Restart=always
SyslogIdentifier=Blog Ghost

[Install]
WantedBy=multi-user.target
EOF

You should now be able to enable the ghost server ("sudo systemctl enable ghost.service") and then start/stop etc the blog ("sudo systemctl start ghost.service").