There are tons of instructions out there already on how to setup a Ghost blog in several systems. There are bitnami images, Digital Ocean droplets and so on. What I couldn’t find, however, is how to do a secure deployment of Ghost (a nodejs application) on Fedora 19. This means, using systemd for controlling the nodejs process and Apache httpd to handle the requests. Extra points for using a MariaDB database instead of the default sqllite. For now, let’s assume that you have already MariaDB and Apache httpd installed and configured, probably already with some hosts. So, here we go!

Downloading

This is the easy part. Just download the ZIP file via wget. I also tried clonning the repo and initializing it, but it seems it’s not that easy. Probably the ZIP file got built with some extra steps, so, for now, it’s easier to just get the ZIP.

Database

I guess it’s not necessary to show how to create an user in MariaDB, but here it is:

CREATE USER 'ghost'@'localhost' IDENTIFIED BY '<password>';
CREATE DATABASE IF NOT EXISTS ghost;
GRANT ALL PRIVILEGES ON ghost.* TO 'ghost'@'localhost' IDENTIFIED BY '<password>';

Installing it

Once downloaded, we need to extract and install the dependencies.

mkdir -p /usr/share/ghost
cd /usr/share/ghost
unzip -q /path/to/file.zip
yum install npm
npm -g install --production
cp config.example.js config.js

Now, just change the /usr/share/ghost/config.js, adapting it to your needs. The MariaDB configuration would look like this:

database: {
    client: 'mysql',
    connection: {
      host: 'localhost',
      user: 'ghost',
      password: '<password>',
      database: 'ghost',
      charset: 'utf8'
    },
    debug: false
},

Systemd

The reasoning behing the use of systemd is well explained in this presentation by Ruben Vermeersch. Our service file is very similar to the one he shows, with a couple of tweaks. It should be placed in /lib/systemd/system/ghost.service

[Service]
ExecStart=/usr/bin/node /usr/share/ghost/index.js
Restart=always
StandardOutput=syslog
SyslogIdentifier=ghost
User=nobody
Group=nobody
WorkingDirectory=/usr/share/ghost
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

At this point, you can try to start your Ghost application:

# systemctl start ghost

If everything is well, you should see this in your /var/log/messages:

Oct 16 16:54:06 perere systemd[1]: Starting ghost.service...
Oct 16 16:54:06 perere systemd[1]: Started ghost.service.
Oct 16 16:54:06 perere ghost[9242]: #033[32mGhost is running...#033[39m
Oct 16 16:54:06 perere ghost[9242]: Your blog is now available on     https://blog.kroehling.de #033[90m
Oct 16 16:54:06 perere ghost[9242]: Ctrl+C to shut down#033[39m

Apache httpd

And the missing piece. Also, there’s no secret on this configuration, which should go somewhere into /etc/httpd/conf.d/

<VirtualHost *:443>
    ServerName blog.kroehling.de
    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/blog.kroehling.de.pem
    SSLCertificateKeyFile /etc/pki/tls/private/blog.kroehling.de.pem
    SSLCertificateChainFile /etc/pki/tls/certs/sub.class1.server.ca.pem
    SSLProtocol all -SSLv2 -SSLv3
    SSLHonorCipherOrder on
    SSLCipherSuite EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS

    ProxyPass / http://127.0.0.1:2368/
    ProxyPassReverse / http://127.0.0.1:2368/

    <Location />
        Options -Indexes
        Require all granted
    </Location>
</VirtualHost>

If you don’t intend to serve your blog via HTTPS, you can safely remove the properties that starts with “SSL”, but I’d highly suggest that you do serve it securely. It costs nothing!