Deploy Ghost instance to Fly.io

Disclaimer: Not affiliated with Ghost or Fly.io, this is only for evaluation purpose.

Fly.io comes with generous free tier allowance, which can be used to run some random side projects for free. Ghost is a WordPress like publishing platform. Unfortunately, there’s no free tier provided by their company. Similar to WordPress, it provides an open-source version that can be self-hosted.

Get Started

To get started, first create an account on Fly.io , and install flyctl :

brew install flyctl

Open your favorite terminal app and sign into the account:

fly auth login

We can view a list of available regions:

fly platform regions

CODE	NAME                        	GATEWAY	PAID PLAN ONLY
ams 	Amsterdam, Netherlands      	✓
arn 	Stockholm, Sweden
...

Deploy Ghost

This article did a great job explaining every steps for deploying to Fly.io . Remember to choose the same region in each step.

Create storage

Free tier offers 3GB volume, so here we create a volume with 3GB:

flyctl volumes create data --size 3

Initialize app

In next step, we initialize the ghost application on Fly.io. See all the latest available Docker images for Ghost .

mkdir my-blog
cd my-blog
flyctl launch --image=ghost:5 --no-deploy

After this step, a fly.toml file will be generated. It contains the configuration for the app we will deploy to Fly.io.

# fly.toml app configuration file generated for fing-ghost on 2023-06-25T19:02:40+01:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = "<your-blog>"
primary_region = "lhr"

[build]
  image = "ghost:5-alpine"

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0

Update config

We need to update the fly.toml configuration file to include some environment variables for Ghost instance. And we mount the volume we created earlier to the application. Make sure to change the port to 2368 which the Ghost instance listens to by default.

app = "<your-blog>"
primary_region = "lhr"

[build]
  image = "ghost:5-alpine"

[http_service]
  internal_port = 2368
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0

[env]
  url = "https://<your-blog>.fly.dev"
  database__client = "sqlite3"
  database__connection__filename = "content/data/ghost.db"
  database__useNullAsDefault = "true"
  database__debug = "false"

[mounts]
  source="data"
  destination="/var/lib/ghost/content"

[[services]]
  internal_port = 2368

Deploy

Simply do:

fly deploy

After a while, the instance should be up and running on https://<your-app>.fly.dev. And we can go to https://<your-app>.fly.dev/ghost to do the initial setup.

Conclusion and thoughts

Fly.io dashboard is a great place to view the status and the logs for the deployed application.

After I played a while, I found that the instance was constantly restarted due to out of memory issue. Their free plan says Up to 3 shared-cpu-1x 256mb VMs.

My thoughts is that: it’s not practical to run a full Ghost instance on Fly.io only on their free plan. However, if you are just interested and want to try it out, then it might be a good place to deploy an application very conveniently. In most case, if you only host a simple blog, then static website hosting (GitHub Pages , Cloudflare Pages , Netlify ) might be better choice.