I’ve been using Ghost for quite some time now for publishing content, mainly through Digital Ocean and its droplets. While the official droplet is great and easy to set up, I’ve always thought it was a bit overkill to run an entire server for just a single blog, and at times annoying to manage.

On top of updates for Ghost, there were constant security and system updates to be managed. Even though the droplet was an official image, it felt unoptimized, and every time I updated anything, I usually had to make sure to set aside at least an hour or two to troubleshoot something breaking.

Over the holiday break, I finally had some time to look into setting up Docker with Ghost which made sense to me. I use Ghost purely as a headless CMS, with the entire frontend through GatsbyJS, and images stored on an AWS S3 bucket.

After a little tinkering, and installing the S3 storage adaptor I've been using on the droplet, I finally got the image working. The next step was to get it hosted somewhere

Ever since Heroku shut down its free hobby plans, I've found Fly.io to be a great hosting platform; not just for free hobby projects, but for larger client projects as well. The entire process with Fly was pretty painless. After a few tries, I was able to get Ghost running on their servers exactly how I wanted using the official Ghost docker image at the latest version, with the following steps:

Install the Fly command-line tools if you don’t have them already:

curl -L https://fly.io/install.sh | sh

or if you’re on a Mac:

brew install fly-io/tap/fly

Create/login to a free Fly.io account

flyctl auth login

This will open a browser window where you can log in to Fly.io and generate an API token.

Deploy an app using a pre-made image of the Ghost blogging platform

flyctl launch —no-deploy 

This will create a new app in your Fly.io account, based on the fly.toml file, but it will not deploy the app yet.

In your fly.toml file, you will need to update the following environment variables:

url - The URL you want to use for your blog

Setup and configure storage for Ghost to store our data in a sqlite3 database that persists through docker redeploys (The included fly.toml is already configured to mount Fly’s storage):

flyctl volumes create data -s 3

Deploy our app!

flyctl deploy

As you can see, this setup is using SQLite over MySQL, mainly because running a MySQL server with Node is too memory intense for Fly’s free tier. However, even with a couple of hundred posts, Gatsby build times and the admin dashboard are still incredibly fast with SQLite, and for the time being, I don’t have a need to switch over just yet.

The current setup is available on Github:

GitHub - underlost/flyio-ghost-s3: A Docker image that runs the Ghost CMS with an S3 storage adapter installed for fly.io
A Docker image that runs the Ghost CMS with an S3 storage adapter installed for fly.io - GitHub - underlost/flyio-ghost-s3: A Docker image that runs the Ghost CMS with an S3 storage adapter install...