Host a Ghost 5.0 Blog for Free on Fly.io In 1 Minute — SQLite edition
Ghost is one of the fastest-growing publishing platforms. However, for those looking to dip their toes in the water, one aspect can be off-putting: the shiny Ghost(Pro) hosting (referral link) starts at $11/month or $108/year — $300/year a year if you want to use your own theme — and even if you self-host on a VPS that will set you back around $5/month or $60 a year. 
For years, I have hosted this blog on Heroku’s free tier. It was a bit involved to get set up, and the in-depth tutorial I wrote still gets traffic. However, when Ghost phased out PostgreSQL support, and Heroku changed their free tier, it became much more difficult.
A little while ago, I ran across Fly.io on HackerNews. It looked like it could run Ghost, and has a generous free tier. When it came time to find a better home for my Ghost blogs, I decided to give it a shot. There are several good tutorials out there, and the process only took about half an hour. I was happy. But what if the process took 30 seconds instead of 30 minutes?
Here is a single copy-and-pasteable command that will spin up a fully functional Ghost blog on Fly.io in less than two minutes:
# Prompt for app name read -p "Enter App Name: " appname </dev/tty && \ # Heredoc wrapper for tidyness (starting now, because we can't seem to prompt for input within heredoc) bash << EOF # Inspect script first if you are leery of pipe-to-bash curl -L https://fly.io/install.sh | sh # This will open a browser, where you can enter a username and password, and your credit card (which is required even for free tier, for fraud prevention). flyctl auth signup # Create a directory for the project and enter it, since the next command will output a file mkdir ghost-flyio && cd ghost-flyio # Create an app -- using Ghost Dockerfile, Seattle region, and app name prompted for earlier -- but don't deploy it echo | flyctl launch --name $appname --image=ghost:5-alpine --region sea --no-deploy --org personal # Provision a volume for Ghost's content and SQLite Database. # Size can be up to 3GB and still fit in the free plan, but 1GB will be enough for starters. flyctl volumes create ghost_data --region sea --size 1 -a $appname # Install sed (stream editor), if it isn't already installed sudo apt install sed # Update the port to Ghost's default (2368) sed -i 's/internal_port = 8080/internal_port = 2368/g' fly.toml # Append info about where to find the persistent storage to fly.toml cat >> fly.toml << BLOCK [mounts] source="ghost_data" destination="/var/lib/ghost/content" BLOCK # Set Ghost url flyctl secrets set url=https://$appname.fly.dev # Since we're using SQLite, we need to set ghost to run in development mode flyctl secrets set -a $appname NODE_ENV=development # Put the SQLite DB somewhere where it doesn't get overwritten on redeploy... fly secrets set database__connection__filename=/var/lib/ghost/content/data/ghost-dev.db # Boom! We're airborne. flyctl launch # End our bash Heredoc EOF
[Shameless plug] once you have your blog up and running, you might want to grab one of my downright gorgeous Ghost themes: Weblog (premium), MNML (free & open source), Laminim (premium), or Undefined (free & open source).
Assuming you don't already have a VPS with free capacity, and the patience to get Ghost configured alongside whatever else you have on it. (When I had space on an AWS T2 instance I needed for other reasons, I ran a Ghost blog on it using Dokku. It was not worth the hassle. However, Coolify looks like a promising self-hosted Heroku/Netlify alternative.) ↩︎
I’m grandfathered in on the original 750 dyno-hour free tier, which is how I can keep this blog running on Heroku for free. ↩︎
Via their Free Postgres databases for small projects blogpost (HN discussion) ↩︎
Okay, okay, calling it a "single command" is maybe stretching it. ↩︎
If you already have a Fly.io account, you can be done in about thirty seconds — depending on region, current load, and your typing reflexes. ↩︎