I've been meaning to upgrade to Ghost v3 for months, but procrastinated over updating my theme to make it compatible.
I wanted some of the nice touches of the v3 flavour of Casper, the rather gorgeous theme that is enabled by default for new Ghost installs.
![](https://cdn.bytes.fyi/content/images/2020/06/bytes.fyi_real-time-goaccess-reports-with-nginx_--1--min.png.pagespeed.ce.DWHNscryfi.png)
![](https://cdn.bytes.fyi/content/images/2020/06/bytes.fyi_real-time-goaccess-reports-with-nginx_-min-1.png.pagespeed.ce.KZuGQn2ttp.png)
![](https://cdn.bytes.fyi/content/images/2020/06/xsmartmockups_kb2ft5lu-1.jpg.pagespeed.ic.77BkjfWWbs.jpg)
![](https://cdn.bytes.fyi/content/images/2020/06/xsmartmockups_kb2frv3e-2.jpg.pagespeed.ic.993vupdZrQ.jpg)
Given that my theme was already a customised Casper v2.11.1, I opted to re-add my modifications to a fresh copy of Casper v3.0.12. I then used the Gscan tool to validate my new theme as best I could.
The upgrade was initially deemed successful, but I soon discovered the automatic resizing to support responsive images was not working properly, when my first article after the upgrade weighed a hefty 5MB! When a request for a resized image was made, Ghost was responding with a HTTP 302 direct to the original image - in all its glory - with terrible consequences for bandwidth and performance.
By coincidence, I'd already been mulling-over moving my blog from the rather crusty Raspberry Pi 2B, where it had been originally built, to a fresh VM on my (amd64) ESXI box.
As much as I love Pis, it's been a bit of a struggle to update Ghost recently... I actually had three Ghost instances running on that poor little Pi:
- bytes.fyi (this blog)
- dev.bytes.fyi (my sandbox for trying out stuff; only accessible locally)
- annholdsworth.co.uk (my wife's blog-to-be, which I've been diligently updating - and paying for the domain - for years and years now; she's never used it)
Using a new VM, I could allocate 2GB RAM, which would really help with running - and updating - three instances on the same box. Also, it would be a novelty to be running the supported stack for Ghost for the first time, err, ever...
So, with a slightly heavy heart and due sense of trepidation, I moved my blog(s) over to a new home.
The steps are listed below as an aide-mémoire for myself.
- Export articles as Json (Settings > Labs) from Ghost
- Backup the
/var/www/ghost/content/images
folder usingtar
- Make a note of the existing settings (especially re: Mailgun config) from the
config.production.json
file - Backup my Isso comments config and (sqlite) DBs using
tar
- Backup my nginx config with
tar
- Spin up a new Ubuntu 18.04 LTS VM and apply all updates
- The usual hardening: firewall, key-based auth (only) for SSH etc
- Install the latest and greatest Nginx, building from source
- Install MySQL, then do MySQL setup steps for Ghost
- Create a new user with no privileges to (install and) run Isso
- Install Isso comments
- Create services for comments.bytes.fyi and comments-dev.bytes.fyi, start and enable them
- Install Node.js 12 LTS via the recommended method
- Configure
npm
to enable sudo-less global package installs - Update
npm
- Install latest
ghost-cli
globally - Create folders for each site and apply correct permissions
- Install Ghost using
ghost install --no-setup-ssl
(because I manage my Let's Encrypt certificate automation separately, on my TLS termination proxy), but don't start Ghost yet - Repeat the previous step for each of the three Ghost instances, making sure that the port numbers are the same as those used on the Pi
- Use
scp
to copy over the backup config files - Restore the backup config, then amend where needed (e.g. host IP in nginx config)
- Temporarily disable WAN access to my Ghost domains, for the initial setup of admin accounts
- Configure my reverse proxy to point 'dev' and 'ann' domains (and comments subdomains) at the new VM's IP
- Configure my ngx_pagespeed proxy to point to the new VM's IP
- Adjust domain mapping in my ngx_pagespeed nginx config, so origin images are grabbed from new VM's IP
- Fire up Ghost using
ghost start
, for each of the three instances - Complete initial setup of admin users for each of the three blogs
- Import content from backup Json file, for each blog
- For bytes.fyi (and dev.bytes.fyi), I use ghostHunter search, so create a new Custom Integration called
ghostHunter
- Update the JavaScript in my custom theme to use the Content Key from the new integration, then apply the updated theme
- Check everything works as expected: creating/amending/publishing articles, importing images, comments, search, etc...
- Restore public access to the blog domains