Skip to content

Instantly share code, notes, and snippets.

@curiositry
Last active September 28, 2022 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save curiositry/910f38b90ee1854c80b4c72998c6101a to your computer and use it in GitHub Desktop.
Save curiositry/910f38b90ee1854c80b4c72998c6101a to your computer and use it in GitHub Desktop.
Run Ghost + MySQL 8 In Production on Fly.io Free Tier (see: https://www.autodidacts.io/host-ghost-mysql8-on-fly-io-free-tier/)
# 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 && \
# 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
# 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 sea --size 1
# 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
# Spin up a second instance for our database server
mkdir ghost-flyio-mysql && cd ghost-flyio-mysql
# Create an app for our mysql
echo | flyctl launch --name ${appname}-mysql --image=mysql:8 --region sea --no-deploy
# 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 sea
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"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[build]
image = "mysql:8"
[mounts]
source="mysql_data"
destination="/data"
[env]
MYSQL_DATABASE = "ghost"
MYSQL_USER = "ghost"
[experimental]
cmd = [
"--default-authentication-plugin",
"mysql_native_password",
"--datadir", "/data/mysql",
"--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 launch
cd ../
# Deploy Ghost application server
flyctl launch
# Boom! We're airborne.
# End our bash Heredoc
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment