My ghost blog is at version 0.7.8 so it's getting a bit outdated with the release of 0.11.3 (and soon the 1.0!). I decided to install it on a Fedora VM and found that there aren't many articles out there.
So here it is: A how-to for installing Ghost on Fedora 25 as a system service and proxied through nginx. If you're more interested in applying my automation efforts on a fresh droplet, I'm working on a script that automates most of the steps in this article.
Prerequisites
This post is specific to Fedora and I'm using DigitalOcean's 1-CPU 512MiB droplet using Fedora 25.
Enable the swapfile for 512MiB VMs
To prevent Ghost's npm install --production
call from failing, a swapfile needs to be created. Read the Fedora manual entry for the quick details, or DigialOcean has a detailed post.
Commands to enable a swapfile:
fallocate -l 1G /swapfile
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile swap swap sw 0 0" >> /etc/fstab
Verify it's enabled with swapon -s
.
Set selinux to permissive
The Ghost service won't start if selinux is enforcing so we want to set it to permissive. I have a TODO
on configuring this properly. Stop the enforcement by modifying /etc/selinux/config
and setting SELINUX=permissive
. Reboot.
Install Ghost
Ghost needs a few OS dependencies then we can use npm to install ghost. However, it's bad practice to use npm
with root so we'll create a ghost
user and fix permissions on the webroot.
Here's how to do the above as root:
# Install deps
dnf install -y nginx nodejs npm python unzip
mkdir -p /var/www/ghost
# Fetch and extract source
pushd /var/www/ghost
curl -L https://github.com/TryGhost/Ghost/releases/download/0.11.3/Ghost-0.11.3.zip -o ../ghost.zip
unzip ../ghost.zip -d .
popd
# Create a system user and fix permissions
useradd --system --create-home --shell /bin/false --user-group ghost
chown -R ghost:ghost /var/www/ghost
# Install Ghost using a non-root account
sudo -H -u ghost /bin/bash -c "cd /var/www/ghost && npm install --production"
If the npm install --production
step fails check that the swapfile is enabled and check permissions. Look at the troubleshooting guide for more tips.
Configuration
This part isn't so much fun. There are a few pieces to configure: systemd unit file for a Ghost service; nginx server; nginx to proxy to ghost; ghost.
Ghost systemd unit file
A nice-to-have is Ghost to start on boot and restart itself after a crash. We can do that by creating a systemd unit file.
Create /etc/systemd/system/ghost.service
:
[Unit]
Description=ghost
After=network.target
[Service]
Type=simple
WorkingDirectory=/var/www/ghost
User=ghost
Group=ghost
Environment=NODE_ENV=production
ExecStart=/usr/bin/node index.js
Restart=on-failure
SyslogIdentifier=ghost
[Install]
WantedBy=multi-user.target
Now scan for the new unit file, enable ghost on boot, and start it:
systemctl daemon-reload
systemctl start ghost
systemctl enable ghost
Make sure Ghost is running with systemctl status ghost
and looking for active (running)
in the output. If it failed: double check permissions, selinux policy, and the installation steps.
Nginx server configuration
This how-to assumes a fresh host and the stock configuration has a conflicting default_server. We'll use the below config and not define a server block.
Create /etc/nginx/nginx.conf
:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
gzip on;
gzip_disable "msie6";
}
NGINX proxy configuration
Our nginx configuration will read configurations from /etc/nginx/conf.d/*.conf
, and that's where we'll create the server block to proxy.
Create /etc/nginx/conf.d/mydomain.conf
with a simple server block:
server {
listen 80 default_server;
server_name mydomain.com;
client_max_body_size 2G;
location / {
proxy_pass http://localhost:2368;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
Have nginx start on boot and start it:
systemctl enable nginx
systemctl start nginx
Use systemctl status nginx
to see if things are working. If so, navigate to http://<yourdomain>
and check that ghost is working. It should be :)
Ghost configuration
Ghost has a default configuration that "works" but it's not ideal. Look at /var/www/ghost/config.example.js
and read the Ghost manual. Be sure to update the file permissions if any new files are added.
Next Steps
With Ghost installed and working you'll want to change the theme. Probably configure a comment service like Disqus. Email and Domain Keys Identified Mail (DKIM) using AWS. Setup HTTPS using letsencrypt. Maybe add a load balancer if you're really cool.
Let me know if this has worked for you!