Setting up my Blog, Part III

In this update, I'll focus on the solution I'll be sticking with for now. My Ghost blog is hosted on a Digital Ocean 'Droplet' and fronted by Cloudflare.

In Part I of this post series, I covered some of my history in trying to get a blog up and running, typically ending in distraction. In Part II I discussed the initial tech stack I intended to proceed with, which focused on using Azure solutions. While those solutions did work, the cost was higher than I felt was reasonable for a hobby blog with no readership. In this update, I'll focus on the solution I'll be sticking with for now. This blog is hosted on a Digital Ocean 'Droplet' and fronted by Cloudflare.

Throughout this personal project I constantly had to remind myself that I had a fixed goal in mind, to have a functional blog that isn't intended as a proof of concept for some tech stack or other. This ultimately led to me exploring some of the suggested implementations Ghost offers. First, and likely simplest, is to pay them to host your blog, SaaS style. Their pricing might be reasonable at small subscriber numbers, but seems to scale quite aggressively, certainly faster than the underlying performance requirements. I generally prefer to have control over my own tech, so this was going to be a very last resort.

For self-hosting, Ghost recommends a Ubuntu system with MySQL and NGINX. There is also a community-maintained Docker image available, which formed the base image for my container based deployment to Azure. The Ghost team offers a middle-ground between their SaaS offering and full self-hosted, a Digital Ocean 'droplet' that comes pre-setup with all requirements and an easy command-line getting-started utility. I've never worked with Digital Ocean, but decided this route met my needs, and the $100 credit offered for using the referral link came in handy later. Digital Ocean's 'droplets' are really just Linux VMs, with some being available with Marketplace images, similar to Azure. While this ended up being convenient for me on short notice, I think much of the same end-result could easily be achieved with an Azure VM, with only slightly more work.

Digital Ocean Droplet Create Screen

There were a few quirks to working with Digital Ocean(DO) that I think are worth mentioning here. First, while DO allows you to scale your droplets, disk size only scales up, not down. My longer-term intention is to use their smallest Basic-type droplet, which comes with 1 vCPU, 1 GB of RAM and a 25GB SSD for ~$5. However, I have a $100/60 day credit and I wanted to take advantage by using a bigger droplet while doing the initial configuration(which ended up being a good call). If on first build, you choose a larger droplet, say the 4 vCPU, 8GB RAM Basic droplet, which comes with a 160GB disk, you can never scale to a smaller size. Instead, choose the smallest size for the initial creation, then scale ONLY the CPU & RAM to the larger size before proceeding.

I also enabled backup, for a very reasonable $1/month and Monitoring, which was free. DO defaults to asking for a public SSH key for authenticating over SSH, which I supplied. DO also presents you with the option to automatically build multiple identical droplets, which is nice, but Ghost doesn't seem to support any form of HA. DO seems to also include a public IP with all droplets, as well as Private IP integration into an automatically built VPC network(similar to a VNET in Azure) for system-to-system communication. A few other typical questions, and I could create my Droplet, which only took a minute or two.

Before proceeding with SSH'ing to the droplet and configuring Ghost, you're going to want to, at minimum, setup a DNS record pointing from a hostname to your new droplet. The Ghost setup includes the configuration of a Let's Encrypt SSL certificate matched to your chosen domain.

I use Cloudflare's free plans for managing DNS for all my domains. I like their tools, extensibility and features, you get a lot for a very good price($0). For this effort, I'm also using their Web Application Firewall, which includes 5 free rules, their proxy which hides the IP of my droplet from the public and their CDN/Caching functionality.

Starting with DNS, I added an A-record, with proxy enabled, to the public IP of my droplet. I also added a cname record, proxied, for the www subdomain to the root domain. This is all you really need to get started.

Cloudflare WAF rules

In the Security section, I wanted to add three firewall rules in the WAF tab.

  1. Block rule for all countries except...
    • (ip.geoip.country ne "US" and ip.geoip.country ne "CA" and ...)
  2. Block rule for all traffic coming from 'Known Bots', as determined by Clouflare
    • (cf.client.bot)
    • This one ended up giving me some trouble with Let's Encrypt, and I've left it disabled for now.
  3. Block rule for all traffic with a 'Threat Score' of medium or higher, as determined by Cloudflare
    • (cf.threat_score gt 14)
Cloudflare Analytics Overview

In the Caching section, I ensured my configuration was set to standard caching and I turned on the Always Online feature, which will attempt to serve static content if my host is down. Over the last 30 days, 45% of my traffic has been served from cache, helping to ensure I stay under any bandwidth caps at Digital Ocean(not that I'm anywhere near them). Cloudflare also provides some nice analytics and performance details.

Ghost sets itself up

With these tasks complete, I could SSH to my droplet and begin the setup process. I HIGHLY recommend temporarily bumping the size of your droplet up for these steps, my first go around was painfully slow and seemed to time-out at several points. You'll first be prompted with a reminder to setup your DNS records prior to proceeding. Ghost will download and install core packages and any dependencies before launching into it's guided setup tool. You're only prompted to provide your blog's URL(the domain or subdomain you setup DNS for) and an email for registering the SSL cert with Let's Encrypt.

After a minute or two of registering SSL-certs, configuring nginx, mysql and user accounts, the Ghost platform is operational and ready for use-case specific configuration, which I won't go into.

And that's it! With about 15-20 minutes of work, you have a robust yet simple blog platform setup, in a way where you can still control most of the underlying components and operate at a nominal cost while still having some good security and performance capabilities.

Mastodon