How to Set Up a Personal Blog with Ghost CMS and Digital Ocean
I would share a step-by-step process, but I think there are already really good resources online on how to do the same, so what I'll be focusing on more is on sharing the resources I followed to help me set up this site, and, more importantly, the problems I ran into along the way.
What is Ghost?
Ghost is an open-source content management system (CMS) that focuses on blogging and newsletters. It's built on Node.js and has over 44.3k stars on GitHub. Like WordPress, Ghost also offers a managed hosting plan with their Ghost(Pro) service, and for the non-technically inclined, that would probably be the recommended approach.
Yeah, I didn't do that. I decided to self-host Ghost since I wanted some experience with using an open-source CMS, and Ghost seems more fresh to me especially since I had spent a lot of years already blogging on wordpress.com. I didn't expect it to be difficult, but I can't believe I made that mistake, since if there's one thing I've learnt from software development, it's that nothing is ever as easy as it seems.
How do you set up Ghost?
I've chosen to set up Ghost on a DigitalOcean droplet, using Mailgun, an API-driven email sending platform, to send emails (which is what Ghost requires for newsletters). This video by David Utke covers the process end to end, but it's not perfect, and there are some things I did differently.
Chose a droplet with 2 GB memory.
Trying to install Ghost with only 1 GB memory didn't really work properly. The install got stuck at the "Linking package dependencies" stage of the npm install
, and after searching for a while, it looks like others suggest using a device that contains at least 2 GB of memory. I made the switch, and what do you know, it works.
Went with the Mailgun Flex plan.
Alright, this one is pretty sneaky. Mailgun doesn't advertise their pay-as-you-grow Flex plan on the site (as of date of publication of this issue), but if you sign up for a trial of their lowest 35-dollars-per-month (!) plan, and then downgrade, you'll be placed on the Flex plan, which is much more cost-effective (and usually free) for small blogs like this.
Used Cloudflare for DNS.
Don't use NameCheap or DigitalOcean. Cloudflare's free plan is sufficient and much, much better than the both of them. Also, it will help to fix a really annoying issue later on when it comes to HSTS.
To do this, simply set up your domain in Cloudflare and set up your name servers in your domain provider. The records (apart from the NS records) will be the same, and the A record should point to the IP of your DigitalOcean droplet.
Remember that your domains should not be proxied at the start (i.e., set to 'DNS Only') so the DNS entries actually propagate. Also, set one Page Rule for <YOUR_DOMAIN>/*
to set SSL to Strict/Full so that you can actually connect to your site. Once the DNS entries propagate, you are free to switch the proxy on for the applicable entries (and is in fact needed for the CNAME entry for Mailgun; more on that below).
Set up Mailgun for transactional emails.
There are two types of email you'll be sending. transactional email (e.g., for new sign-ups, forgot password features etc.), and bulk email (for newsletters). While the above video covers how to use Mailgun for newsletters, it doesn't cover how to setup transactional email. Ghost, by default, uses direct SMTP for transactional email, but this doesn't work through DigitalOcean.
Since we're using Mailgun for bulk email anyways, we might as well use it for transactional email as well. This video by Dave Swift shares the process, but it's subject to the below two caveats as well.
Used the same domain for Mailgun.
There's no real reason to use a different domain for Mailgun, when you can specify a subdomain instead (e.g., mail.rohanav.com instead of rohanav.com). In fact, it's recommended to keep transactional and bulk emails separate on Mailgun by specifying two different subdomains.
Despite this, I decided to be a bit naughty. I didn't even use a subdomain. I used the exact same domain (rohanav.com), since I wanted Cloudflare's default (free) certificate to cover it. Why? That's where the next section comes in.
Enabled TLS for outbound email links.
This is an essential step if your site is only served on a secure connection. Since the links on the buttons within the email are non-secure by default, you'll run into issues due to HSTS, as Ghost sets the site up in such a way that you can only interact with it using HTTPS.
While those on Mailgun subscription plans simply have the setting to do so (on the same Domain Settings page close to the Tracking section), Flex plebeians like ourselves have a more complicated process, as outlined in this article. I think you can see why I switched to Cloudflare, as their Page Rules functionality is what makes this possible. This is also why I had gone with just my domain name for Mailgun.
I made the following cURL request to switch outbound links to use TLS, because I didn't want to wait for a support ticket to be answered:
curl -s --user 'api:<YOUR_API_KEY>' -X PUT https://api.mailgun.net/v3/domains/<YOUR_DOMAIN> -F web_scheme='https'
The Page Rule mentioned in the linked article should also be placed at a higher priority than the one you had previously set up for <YOUR_DOMAIN>/*
. So it should look something like this:
I hope this article has been interesting, and thanks for reading until the end. Just to reflect for a while: setting up a self-hosted CMS has actually taught me a fair few things, especially regarding DNS. Sure, I'm not really coding anything out, but there's just something about learning how critical infrastructure works that puts the sheer complexity of the Internet into perspective.
Also, another thing to reflect on: self-hosting isn't necessarily cheaper than just letting Ghost do everything for you with a Ghost(Pro) subscription. I tried to lower costs as much as possible, but I still have a monthly cost of ~13 SGD (~10 USD) a month (domain + hosting). Meanwhile, Ghost(Pro) is 9 USD monthly with upfront yearly billing (for up to 1000 members). Really, the only benefit in doing self-hosting is if you're technically inclined and want to learn. Otherwise, supporting the Ghost team with a Ghost(Pro) subscription is the way to go.
And that's all I have to say for now. See ya next time!