For the sake of others
MySQL is not part of Ghost’s docker image, so you need to install it separately, when doing that you realize the real issue: MySQl8 needs a lot more RAM than fly.io offers and what most hosting platforms offer. Bare minimum one seemingly needs 2GB RAM
Conclusion: Hosting Ghost on fly.io’s (free tier) is no longer an option (PlanetScale is NOT an option for Ghost)
For the sake of others
you might want to try making the connection string use the appname as the host so change
Thanks, but as per my comment above. Even if connections are fixed, the real issue is fly.io 's RAM offer does not allow for a MySQL8 deployment (one needs a minimum of 2GB RAM). Sadly. And PlanetScale is not an option for Ghost.
fly.toml for Ghost with MySQL - #2 by patfly
Planet scale mysql won’t work for ghost? Does it also need mysql 8 instead of 5.7+?
I can’t find specific info on that - Just curious!
Here: PlanetScale does not work with Ghost. Mainly because Ghost makes heavy use of foreign key constraints, a feature PlanetScale does not support → How to run PlanetScale as database for Ghost CMS? · Discussion #88 · planetscale/discussion · GitHub
And yes using MySql8 is a breaking change for Ghost → When will MySQL 8 be mandated? Which ver? - Developer help - Ghost Forum
For this reason (mainly because of RAM requirements for MySQL8) a fly.io build can’t even be tried on the free tier. Let alone run in production which is sad given a bunch of ghost tutorials online are guiding people to fly.io only for one to realize later it won’t work. Conclusion: One can no longer host Ghost in fly.io’s free tier.
For anyone reading this thread, the problem of MySQL 8 on the Fly free tier has be solved by Chris & Will over in this thread:
Ghost can now be deployed in production on Fly’s free tier with MySQL 8! Here’s a tutorial with the script I used:
@Curiositry Hi there! Deployment worked. Thanks a ton for your tutorial!!
Wanted to ask: How to update Ghost with this setup?
@patfly Just redeploy, and it pulls in the latest Ghost v5 docker image (currently v5.17.0, v5.17.1 hasn’t made it to the docker hub yet.)
Hi again, so I’m running the
flyctl launch --name $appname --image=ghost:5-alpine --region sea
(I have replaced $appname with my app name)
but I’m getting:
Error Validation failed: Name has already been taken
Would you have any pointers?
Scratch that, for others in future just run:
flyctl deploy --image=ghost:5-alpine --region sea
Yeah, sorry, I wasn’t very clear. You can just run:
… from the directory with your fly.toml, or
fly deploy -a [APPNAME]
from anywhere else.
Many thanks for the clarity @Curiositry . I appreciate all help.
Got something else earlier today that I’m stuck with.
I’ve added a custom domain and all good with that, I’m having issues with the metadata passed on to Google, Twitter, Facebook (located in Settings → Site Meta settings). My custom domain is not beeing passed on in that case, everywhere meta data is passed on my url shows up as being the appname.fly.dev domain (and not my custom domain).
I’ve tried setting up an env url in fly.toml to deal with that but no luck so far.
Would you know how to modify that metadata?
You may just need to re-deploy in order to get Ghost to “restart” (which may make it recognize the domain). That guess is based on this.
Sometimes that kind of error is related to the app not picking up reverse-proxy related HTTP headers such a
X-Forwarded-For but I don’t think the hostname is usually picked up incorrectly in those cases (usually it’s more like generated URL’s use
http:// instead of
Thanks @fideloper-fly for the nudge.
The issue was with embedly’s cash. With time, the custom domain propagated.
Hi there, me again! Sorry.
Struggling to get the Ghost/Signup/transactional emails to work (working with the Mailgun integration since it is the default one), by only setting up Mailgun details in Ghost dashboard I get “Failed to send magic link email” See screenshot:
Then I understood the mailgun setup via the ui is for bulk newsletter emails (not for auth/login)
There are two mail delivery setups:
- Transactional email - this is set via the config file and used for one-off emails like member signups, staff invites, etc
- Bulk email - only Mailgun is supported and is set through the UI, used for sending newsletters to members
You’ll need to configure both for a fully working setup.
So reading Ghost’s documentation I also need to add some Mailgun details to add credentials to
config.production.json → See mail under Configuration - Adapt your publication to suit your needs
Since the only config file I have is fly.toml I’ve attempted the following under fly.toml’s [env]:
[env] url="xxxxx" [mail] transport = "SMTP" [mail.options] service = "Mailgun" host = "smtp.eu.mailgun.org" port = 587 [mail.options.auth] user = "xxxx" pass = "xxxxxx"
and for that I’m getting
Error unknown attribute 'mail' for AppConfig. raise UnknownAttributeError.new(self, k.to_s) ^^^^^
Without making transactional emails (i.e. login, etc) work, Ghost is non-functional.
Unsure where to provide those additional credentials. Pointers welcome
I don’t think that’s a valid
What you probably want is migrate from just putting your image on
fly.toml to using a Dockerfile because Ghost image doesn’t support mail variables (?).
I haven’t tried it but it could be a Dockerfile like:
FROM ghost:VERSION_HERE COPY config.production.json /the/folder/ghost/stores/data
After that remove the image portion from your Dockerfile and
flyctl would pick the Dockerfile for the build.
Thanks for the pointer! Appreciated.
For others reading this in the future: I’ve managed to get the mail variables through as environment variables via secrets (and not via fly.toml).
So, for those struggling, here they come:
flyctl secrets set mail__transport=SMTP
flyctl secrets set mail__options__host=smtp.eu.mailgun.org
flyctl secrets set mail__options__port=587
flyctl secrets set mail__options__auth__user=xxxxx
flyctl secrets set mail__options__auth__pass=xxxx
@patfly Sorry I didn’t see your post until you had figured it out.
Like you, I have my transactional mail config set via fly secrets, using the convention for environment variables described in the Ghost docs: https://ghost.org/docs/config/#running-ghost-with-config-env-variables
Technically, you should be able use env variables in the fly.toml, but I suspect it would need look like:
[env] mail__transport = "SMTP"
I haven’t tried it, though, since fly secrets work well enough.
I am curious why Ghost’s direct mail doesn’t seem to work on fly.
Just FYI, back to the original question, it’s still possible to configure the latest Ghost version with sqlite and get it running on Fly.
Here’s the relevant parts of the config I’m using:
[env] database__client = "sqlite3" database__connection__filename = "content/data/ghost.db" database__useNullAsDefault = "true" database__debug = "false" [mounts] source="data" destination="/var/lib/ghost/content"