
Deploy Ghost | Publishing Platform with MySQL and a Real Volume
Self-host Ghost on Railway: pinned release, MySQL, content that persists
MySQL
Just deployed
/var/lib/mysql
Ghost
Just deployed
/var/lib/ghost/content
Deploy and Host Ghost on Railway
Ghost is a publishing platform: posts, pages, themes, members and paid newsletters, with an editor built for writing rather than for page-building.
About Hosting Ghost
This template runs the official ghost image on a pinned release, with MySQL and a persistent volume mounted at the content directory.
Both of those matter. Ghost keeps posts and members in MySQL, but themes, uploaded images and generated files live on disk under /var/lib/ghost/content. Without a volume every image you upload disappears with the next deploy, and the site keeps rendering broken links to files that are no longer there.
The image is pinned to a specific Ghost release instead of a moving tag, so a redeploy gives you the version you were running, not whatever shipped this morning.
Common Use Cases
- A blog or company publication you own, on your own domain
- A paid newsletter with members and subscriptions, without a per-subscriber platform fee
- A documentation or changelog site fronted by a custom theme
Dependencies for Ghost Hosting
- MySQL 8, included in this template. Ghost supports MySQL in production; SQLite is development-only.
- A persistent volume, included, for themes, images and other uploaded files
- SMTP credentials if you want member sign-in emails and newsletters. Add them as mail__* variables - Ghost runs without them, but no email leaves the site.
Deployment Dependencies
- Ghost documentation: https://ghost.org/docs
- Configuration reference: https://ghost.org/docs/config
- Source: https://github.com/TryGhost/Ghost
Implementation Details
Open the site once it is up and go to /ghost to create the owner account. That first account owns the site.
Configuration is passed the way the official image expects, as double-underscore environment variables:
| Variable | Why |
|---|---|
| url | The public address. Ghost writes it into links, feeds and emails, so it has to be right from the first boot |
| database__client, database__connection__* | Point Ghost at the bundled MySQL over the private network |
| PORT, server__port, server__host | Ghost listens on 2368; PORT is what Railway routes the public domain to |
| NODE_ENV | Production mode, so Ghost uses the configured database rather than a development fallback |
The Ghost service restarts on failure. That is deliberate: on a cold start MySQL can still be initialising when Ghost first tries to connect, and Ghost exits rather than waiting. The retry brings it up once the database is ready, usually within a minute.
Why Deploy Ghost on Railway?
A self-hosted Ghost needs a database, a disk for uploads and a domain with TLS. Railway provides all three on a private network from one deploy, and the volume means your images are still there after the next release lands.
Template Content
MySQL
mysql:8.4Ghost
ghost:6.54.0-alpine