While reading angristan's blog, I caught myself comparing: his site was fast and incredibly sexy, my site took a few seconds to load, and the fonts looked wacky . His post, or rather, my envy, inspired me to get cracking. I sat down yesterday to clean up and update my Casper theme... It's been two days and I'm almost done.

TL;DR: I updated my Ghost theme, set up always HTTPS, and configure my nginx server  to redirect www URLs to non-www.

Theming

I started by forking a fresh release of Casper, applying some of his changes and a couple more of my own:

  • Add classy looking fonts, hosted locally using Google Fonts Helper.
  • Add Utterances comments.
  • Add Github, LinkedIn, Email Links Icons.

Ghost 2.0 recently brought responsive image sizes, but your theme also needed to implement it. I had upgraded to 2.0 in December, but since my theme was from 2017, my site was still loading huge images to resize into smaller containers. Ergo, the tweaks brought an unexpected speed boost.

After the changes, a yarn zip, and an upload later, I see this:

This is actually demo.ghost.io, but you get the point. 😛

IMAGES WEREN"T LOADING!!! Apologies for the outburst, but that's how I felt after making all those changes, seeing it work locally, but then breaking on prod. Some googling made me realise images were being served over HTTP instead of HTTPS, so Chrome was blocking them.

Ah, xkcd gold.

Setting up HTTPS

First, I checked my Ghost URL (you need to run this inside your Ghost directory. For DigitalOcean droplets, it's at /var/www/ghost):

ghost status

Evidently, it was http://blog.maskys.com. I changed it using:

ghost config url https://blog.maskys.com

Somehow, I already had my certificate setup, but if you don't have one, run:

ghost setup nginx ssl

A wild bug appears

There, now we have a Let's Encrypt SSL certificate. ghost restart, fingers crossed... Works! But wait, it doesn't end here. I noticed the cover image still didn't load. Ctrl+Shift+I revealed that the image url was  https://www.blog.maskys.com/image_url_here. It was only then that I realised that www URLs weren't set up.


Redirect www to non-www

Here's what I had to do:

  1. Add an A record with the name set to www.blog (might be www if you're not using a subdomain) and the value set to the IP of my droplet.
  2. Wait. DNS propagation can take up to 24 hours, and you will encounter errors if this hasn't been done yet.
  3. Temporarily switch Ghost to the secondary domain:
ghost config url https://www.blog.maskys.com

4. Grab an SSL certificate for the www.blog subdomain:

ghost setup nginx ssl

5. Set the Ghost URL back to the primary domain:

ghost config url https://blog.maskys.com

Since Ghost itself can only have one domain pointed to it, we need to redirect requests to the non-www sub-domain, https://blog.maskys.com. For this, you need to crack open some nginx configuration files. Mine on DO were at /etc/nginx/sites-available/. They have a link at /var/www/ghost/system/files/ as well.

I had to replace the contents of the location /  block in blog.maskys.com.conf(This one as well so we're always serving HTTPS), www.blog.maskys.com.conf, and www.blog.maskys.com-ssl.conf (but not blog.maskys.com-ssl.conf!) with:

return 301 https://blog.maskys.com$request_uri;.

This is what the files look like now:

Bam! All done. Let's write a new post so I can save someone else the trouble. I just need to head over to the content tab...

BAM! (again). 500 server error.

me at this point

Everything else was functioning fantastically. Inspecting the site revealed some weird JS errors, none of which were google-able. I tried to replicate the error locally, but it worked just fine there. What. My head was hurting by now. As a last-ditch effort, I SSHed into my server and updated Ghost to the latest version. Reload... Phew. Bug squashed.

Make fast faster.

Since I was this engrossed, I decided I might as well as go full throttle. This post is getting quite long, so you can check how I sped up Ghost in part 2.