Upgrading to Ghost 5.105

Upgrading to Ghost 5.105

A quick technical post to document a few hiccups I ran into and overcame when upgrading this here blog to the latest Ghost version as of this writing. I run this blog on Reclaim Cloud (big fan!) and used their built in Ghost installer which works a treat not only for turning what can be a complicated install process for the open source version into a one-click action but also has addons to make the domain mapping and email setup painless. There's a great support article at https://support.reclaimhosting.com/hc/en-us/articles/8024410882839-Running-Ghost-on-Reclaim-Cloud that covers all the various how-tos of getting it setup.

My install may predate the "Update Ghost" addon and I don't know of an easy way to add that, though I suspect my process mirrors what the addon does which is that I open an SSH connection to my install, navigate to /root/ghost/ and run the command docker-compose pull && docker-compose down && docker-compose up -d. Essentially three commands in one it pulls the latest images of Ghost, nginx, MySQL, and a Let's Encrypt proxy and then shuts down the existing docker containers and brings them back up with the new images. Usually not an issue but this time after running it my site was still offline which meant something had gone wrong (It had been quite awhile since I had updated so I suspected I might have to roll up my sleeves and dig in a bit).

Luckily this timmmmyboy hasn't lost his chops just yet. As the support article mentions it's possible to see the logs for the various containers running in this stack with docker-compose logs -f. I also like to run docker ps -a to see the status of the various containers. I could immediately see that both the Ghost and MySQL container were down. Ghost because it couldn't connect to MySQL and MySQL because an upgrade had failed. The particular error was Invalid MySQL server upgrade: Cannot upgrade from 80033 to 90100. Upgrade to next major version is only allowed from the last LTS release, which version 80033 is not. Seemed to me like the docker-compose.yml file I had was set to just upgrade to whatever the latest MySQL version out there was, but that my MySQL 8 version was too old to be attempting an immediate jump to a major version. I went in and forced MySQL 8 in the file by editing the Mysql portion to image: mysql:8. (Ghost also only supports MySQL 8 at this time)

After pulling the new images and restarting the containers again with the same upgrade command all the containers started and the MySQL error was gone. That's progress, but the site was still offline. Taking a look at the logs again the new issue was that Let's Encrypt was trying to update the SSL cert for the site, but was not able to verify the DNS was pointed. The way this stack works the Let's Encrypt proxy container works with the nginx container to setup the appropriate bypass URLs and add the necessary text file that Let's Encrypt uses to verify ownership and issue a cert. I was a bit lost on what to do at this point but I figured I'd start by looking around the web for anyone that might have the same issue with the proxy image. What I found was that the image in use (jrcs/letsencrypt-nginx-proxy-companion) was deprecated but perhaps would still work with a few additional lines in the docker-compose file. In particular I would need to add some information on the Acme process that allows the verification to complete. A few back and forth attempts and the following updates to nginx and Let's Encrypt in the docker-compose file worked and got the SSL cert renewed and the site back online:

 nginx-proxy:
    image: nginxproxy/nginx-proxy
    volumes:
      - certs:/etc/nginx/certs
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    ports:
      - "80:80"
      - "443:443"
    networks:
      - ghost
    restart: unless-stopped
    
  nginx-proxy-acme:
    image: jrcs/letsencrypt-nginx-proxy-companion
    volumes:
      - acme:/etc/acme.sh
      - /var/run/docker.sock:/var/run/docker.sock:ro
    volumes_from:
      - nginx-proxy
    networks:
      - ghost
    restart: unless-stopped

volumes:
  certs:
  acme:

All is well that ends well as I'm back up and running and fully up to date now. Long live the blog!