Host a reliable Ghost blog for $5/mo

For folks like me that are looking for a fast and simple blogging platform without a lot of bloat, the Ghost platform might just be the perfect solution. However, unless you're a frequent blogger, it can be hard to justify the monthly hosting cost even at the lowest tier. Luckily, there's a more affordable way of hosting Ghost yourself with a little elbow grease.

Ghost itself is a fully open source blog platform that can be hosted on any server that supports Node.js. While there are a few cloud services that have this capability, I have found DigitalOcean to be my favorite considering both cost and reliability. Unfortunately, their smallest droplet at $5/mo doesn't support one-click Ghost installs (not enough RAM) so a few extra hoops have to be jumped through to make it work.

The basic premise of bypassing the limitation is to set up the smallest droplet with SWAP memory (using hard drive storage as RAM) so that Ghost can install sucessfully. Here is the best guide I have found on how to do this:

Running Ghost on a $5 Digital Ocean VPS
Dan Walker

Before you run off to follow the guide above, here are a few tips that will save you some time and frustration if you are fairly new to creating your own server:

1. Use nano instead of vim

Both are text editors but nano is much more newbie friendly. Simply use nano filename in place of vim filename. All the commands you need are listed at the bottom of the editor (e.g. ^X to save; it'll ask if you want to write to file).

2. Get SSL certificate for WWW and non-WWW sub-domains

Regardless of whether you like the WWW prefix or not in URLs, you should probably get SSL certificate for both sub-domains. You can do this by adding -d www.example.com to your certbot (LetsEncrypt) command before running it. In fact, you can add as many Subject Alternative Name (SAN) to the same SSL certificate by repeating the parameter; like so: sudo certbot certonly --webroot --webroot-path=/var/www/ghost -d example.com -d www.example.com -d example2.com -d www.example2.com.

If you have already executed the command before reading this, just re-run it again with the right parameters but add --expand to the end to update the certificate instead of trying to generate the same one.

3. Point HTTP to HTTPS for all sub-domains

After Ghost has been installed using the SSL option, it'll generate two nginx config files; example.com.conf and example.com-ssl.conf. You can the configuration by routing all HTTP URLs to the same HTTPS location. Run sudo nano /etc/nginx/sites-available/example.com.conf and replace the content with the following:

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

What this will do is direct all users to the HTTPS non-WWW version of the website. Don't wory about changing anything inside /etc/nginx/sites-enabled/; the files here are all just links of the /etc/nginx/sites-available/ folder.

4. Fix SSL certificate location

If you followed the original guide and created the SSL certificate first before installing Ghost, you need to point nginx to the right certificate location instead of the one Ghost made. Do so by editing the SSL version of the config by running sudo nano /etc/nginx/sites-available/example.com-ssl.conf. Update the ssl_certificate and ssl_certificate_key rows to the right location (the one returned by the certbot command); you can just replace the paths:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com www.example.com;
    root /var/www/ghost/system/nginx-root;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /var/www/ghost/system/files/ssl-params.conf;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;

    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

5. Add Yarn public key

This one isn't necessary for getting Ghost running, but if you ever run apt-get update to update applications in the future, you will get an error because the original guide did not include a command to add the Yarn public key. Fix this by running curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - to save some headaches down the road.

6. Don't forget to reload nginx

Once you've completed everything, don't forget to test and restart nginx via these commands, respectively: sudo nginx -t and sudo service nginx restart.

7. BONUS: Run multiple blogs on the same droplet

If you have multiple blogs (or multiple friends who need blogs), you can create even more savings by hosting several blogs on the same droplet -- as long as each blog isn't too taxing on the server. I won't get into the details but the general gist is to duplicate the content of the Ghost folder into separate folders, then go into each to configure separate ports for each blog. Finally, you will modify nginx to route domain requests to the right port and voila, multiple blogs running simultaneously. DigitalOcean themselves have created a pretty good tutorial on this subject.

Joseph Siu

Joseph Siu

Up in the air is my happy place.
Los Angeles, CA, USA