This blog runs on Ghost on fly.io's (now deprecated) Hobby plan tier. In this post, I'll share how I arrived at this setup as well as two tips that might help others trying to host a Ghost blog in a cost effective way.
How I Got Here
My journey began with some not-quite-cursory-yet-not-overly in-depth researching of blogging solutions that could be run for free. I looked at static site generator blogs (wasn't sure I wanted to be doing a site rebuild whenever I published a new post) and commercial services (Substack, Wordpress). Ultimately I stumbled across Ghost and liked that it was open source and self-hostable.
Originally this site was hosted on Heroku's free tier. I was able to find a Heroku button that set up Ghost on Heroku and after some trial and error, got this site up and running. Fast forward a couple years and Heroku announced they were ending their free pricing. Some quick googling and came across fly.io (it might have been through HN but I'm not sure), who were positioning themselves as a place for Heroku escapees to land, with solid capabilities and a generous free tier.
Getting Ghost working on fly.io was a bit bumpy at the beginning - there wasn't a lot of information on how to do it. Fortunately, I stumbled upon an excellent guide from autodidacts.io. It walked me through the process of setting up Ghost with MySQL 8 on fly.io's free tier. If you're considering a similar setup, I highly recommend checking out their guide as a starting point.
Two Useful Tips from My Experience
While the initial setup process went smoothly, I encountered a few challenges along the way. Here are some tips that might help fellow bloggers:
1. Handling Ghost Upgrades and Database Changes
Certain Ghost upgrades introduce changes to MySQL tables that may not get implemented correctly when using a fly.io instance. If you encounter issues after an upgrade, follow these steps:
- Use fly.io's remote database access feature to connect to your MySQL database. You can find instructions in the fly.io documentation.
- Once connected, you'll need to manually implement the database changes. To identify these changes:
- Visit the Ghost GitHub repository
- Look for the migration files corresponding to your upgrade
- Apply the necessary changes using MySQL commands
- Important: After making the changes, don't forget to clear the migration lock table in MySQL. Otherwise your fly.io re-deployment will fail.
2. Use swap_size_mb in fly.toml
In my last upgrade cycle, my Ghost application machine kept running out of memory while starting up. Adding some swap resolved the issue.
Conclusion
Running my Ghost blog on fly.io's free tier has been an ongoing learning experience. I find I've got a good balance of control, performance, and cost-effectiveness. While there might be a slight learning curve, especially when dealing with upgrades, the benefits far outweigh the occasional challenges.
Hope what I've learned helps others. Good luck!