|Docs

Self-host Ghost with MySQL and Custom Themes

deploymentfrontendghostcms

Ghost is an open-source publishing platform for blogs, newsletters, and membership sites. It includes a visual editor, built-in SEO, membership and subscription management, and a theme system.

This guide covers deploying Ghost on Railway from the official Docker image with a MySQL database and persistent content storage.

What you will set up

  • A Ghost instance from the official Docker image
  • A MySQL database for content storage
  • Persistent storage via a Railway Volume for themes, images, and settings
  • A public domain with SSL for the Ghost site and admin panel

One-click deploy from a template

Railway has a Ghost template:

Deploy on Railway

After deploying, generate a domain and update the url environment variable to match. Open /ghost to access the admin panel.

If you prefer to set things up manually, continue with the steps below.

Deploy manually

1. Create the project and database

  1. Create a new project on Railway.
  2. Add a MySQL database: click + New, then Database, then MySQL.

Ghost requires MySQL. It does not support Postgres.

2. Deploy the Ghost Docker image

  1. Click + New, then Docker Image.
  2. Enter ghost:5-alpine as the image name.

3. Configure environment variables

Add the following variables to the Ghost service:

Ghost uses double-underscore (__) notation for nested configuration. Set the url variable after generating a domain in the next step.

4. Add persistent storage

Ghost stores themes, images, and other content in /var/lib/ghost/content. This directory must persist across deploys.

  1. In the Ghost service, go to Settings, then Volumes.
  2. Add a volume with the mount path /var/lib/ghost/content.

Without a volume, all uploaded images and custom themes are lost on each deploy.

5. Generate a domain

Navigate to Networking in the service settings and generate a domain. Update the url variable to match (e.g., https://your-blog.railway.app).

The url variable must include the full URL with https://. Ghost uses it to generate absolute links for posts, images, and the admin panel.

Open https://your-domain.railway.app/ghost to create your admin account.

Custom domain

To use your own domain:

  1. Add a custom domain to the Ghost service in Railway.
  2. Update the url variable to match your custom domain (e.g., https://blog.example.com).
  3. Railway provisions an SSL certificate automatically.

Custom themes

Ghost ships with a default theme (Casper). To use a custom theme:

Option 1: Upload via admin panel. Go to Settings > Design > Change theme > Upload theme in the Ghost admin. Themes uploaded this way are stored in the content volume and persist across deploys.

Option 2: Build into the Docker image. Create a Dockerfile that copies your theme into the Ghost image:

Deploy this Dockerfile from a GitHub repository instead of using the public Docker image. The theme is built into the image and does not require a volume for persistence.

Sending email

Ghost uses email for member sign-ups, newsletters, and password resets. Configure an SMTP provider by adding these variables:

Replace with your SMTP provider's credentials. Ghost supports Mailgun, SendGrid, and any SMTP service.

Connecting a frontend

Ghost provides a Content API for headless use. Generate a Content API key in the Ghost admin under Settings > Integrations.

For a full headless setup, use the Ghost Content API with a separate frontend framework.

Next steps