On this page

This post is an update to this post from Curiositry, I highly recommend you read that first. I tried his script to create this site with Ghost on Fly.io but ran into a few issues, here are my solutions.

Error #1: The instructions for using MySQL v8 kept giving me a 500 error, Ghost couldn't connect to the database, no matter what I did.

This was the error:

Invalid database host.

"Please double check your database config."

Error ID:

500

Error Code:

ENOTFOUND

Switching to MySQL v5.7 fixed it.

Error #2: The script kept trying to create the MySQL instance on a different region than the Ghost instance; this is a big no-no on Fly.io

Adding the region ( primary_region = 'ADD_YOUR_FLY_REGION_HERE' ) to the ghost-flyio/ghost-flyio-mysql/fly.toml file fixed it.

Error #3: The Ghost instance kept refusing connections, and I couldn't see the website on my browser.

This was the error:

instance refused connection. is your app listening on 0.0.0.0:8080? make sure it is not only listening on 127.0.0.1 (hint: look at your startup logs, servers often print the address they are listening on)

This was a Ghost configuration issue; adding this to the ghost-flyio/fly.toml fixed it:

[env]
server__host = "0.0.0.0"
server__port = "8080"

With all of this solved, here's the updated script:

# Prompt for app name
echo -n "Enter App Name: " && \
read appname && \
echo -n "Enter MYSQL password: " && \
read mysqlpassword && \
echo -n "Enter MYSQL Root password: " && \
read mysqlrootpassword && \
echo -n "Enter Region: " && \
read region && \

bash << EOF
# Uncomment following line for debugging (prints each command before running)
set -x
# Check if Fly CLI is installed, and install it if it isn't
# Inspect script first if you are leery of pipe-to-bash
command -v flyctl >/dev/null 2>&1 || { echo >&2 "Fly CLI required and not found. Installing..."; 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 docker image, your chosen region, and app name prompted for earlier -- but don't deploy it
flyctl launch --name $appname --image=ghost:5-alpine --region $region --no-deploy --org personal
# Provision a volume for Ghost's content
# 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 $region --size 1 --auto-confirm
# Install sed (stream editor), if it isn't already installed
command -v sed >/dev/null 2>&1 || { echo >&2 "sed (Stream EDitor) required and not found. Installing..."; 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

# Spin up a second instance for our database server
mkdir ghost-flyio-mysql && cd ghost-flyio-mysql
# Create an app for our mysql
flyctl launch --name ${appname}-mysql --image=mysql:5.7 --region $region --no-deploy --org personal
# If you aren't trying to stay within the free tier, uncomment this to give the MYSQL VM 2GB of ram
# fly scale memory 2048
# Create a persistent volume for our MYSQL data
fly volumes create mysql_data --size 1 --region $region --auto-confirm
fly secrets set MYSQL_PASSWORD=$mysqlpassword MYSQL_ROOT_PASSWORD=$mysqlrootpassword
# Add our database credentials to the Ghost instance
fly secrets set database__client=mysql
fly secrets set database__connection__host=${appname}-mysql.internal -a $appname
fly secrets set database__connection__user=ghost -a $appname
fly secrets set database__connection__password=$mysqlpassword -a $appname
fly secrets set database__connection__database=ghost -a $appname
fly secrets set database__connection__port=3306 -a $appname
fly secrets set NODE_ENV=production
cat > fly.toml << BLOCK2
app = "$appname-mysql"
primary_region = '$region'
kill_signal = "SIGINT"
kill_timeout = 5
[build]
image = "mysql:5.7"
[mounts]
source="mysql_data"
destination="/data"
[env]
MYSQL_DATABASE = "ghost"
MYSQL_USER = "ghost"
[processes]
app = "--datadir /data/mysql --default-authentication-plugin mysql_native_password --performance-schema=OFF --innodb-buffer-pool-size 64M"
BLOCK2
# Note: if you aren't trying to stay within the free tier, you might want to remove the performance schema and buffer pool size flags above.
# Deploy MySQL server.
flyctl deploy
cd ../
# Deploy Ghost application server
flyctl deploy
# Boom! We're airborne.
# End our bash Heredoc
EOF