Skip to main content

Self-Host Ghost with Docker Compose

Ghost 5 needs MySQL 8 for production. SQLite works for local experiments but is not supported for a live site, and PostgreSQL is not supported at all. Two more settings are mandatory: url, the public address of the blog, and a persistent volume at /var/lib/ghost/content, which holds images, themes and the SQLite-independent content files.

Before using the one-click template, here is a minimal Docker Compose example for self-hosting Ghost.

If you're new to Docker Compose, check out our guide on how to self-host a Docker Compose app. More stacks are in our Docker Compose library.

Self-host Ghost with Docker Compose (minimal)

services:
ghost:
image: ghost:5-alpine
ports:
- "2368:2368"
environment:
url: http://localhost:2368
database__client: mysql
database__connection__host: ghost_db
database__connection__user: ghost
database__connection__password: changeme
database__connection__database: ghost
volumes:
- ghost-content:/var/lib/ghost/content
depends_on:
- ghost_db

ghost_db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: changeme-root
MYSQL_DATABASE: ghost
MYSQL_USER: ghost
MYSQL_PASSWORD: changeme
volumes:
- ghost-db:/var/lib/mysql

volumes:
ghost-content:
ghost-db:

Set url to the address readers will actually use, including https:// once a domain is in front. Ghost writes that value into every link it generates, so a wrong url produces a site that loads but sends visitors to the wrong host.


Deploy Ghost on Hostim.dev (one-click)

Ghost is an open-source publishing platform for blogs, newsletters and paid memberships. On Hostim.dev the template runs ghost:5-alpine against a managed MySQL database, mounts the content volume, and sets url to the project domain — so the blog is reachable over HTTPS as soon as it boots.

✍️ Your blog, your database, your domain — no platform fee on subscriptions.

Try it Yourself

Guest project runs for 1 hour. Log in to save and extend to 5 days.

Why host Ghost on Hostim.dev?

  • One-click Docker deployment, no server setup
  • Managed MySQL 8, which Ghost requires in production
  • Persistent volume at /var/lib/ghost/content for images and themes
  • url set to your project domain automatically
  • Automatic HTTPS and domain
  • Real-time logs and metrics

What's included

ResourceDetails
Appghost:5-alpine image
DatabaseManaged MySQL
Volume/var/lib/ghost/content
DomainFree *.hostim.dev subdomain
SSLLet's Encrypt (auto-enabled)
Port2368

How to Deploy

  1. Go to your Hostim.dev dashboard.
  2. Click Create ProjectUse a Template.
  3. Select Ghost Blog.
  4. Choose a resource plan.
  5. Deploy.

First steps after deploy

  1. Open /ghost on your domain and create the owner account. Do this immediately — until the account exists, anyone who finds the URL can claim the blog.
  2. Set the site title and description in Settings → General.
  3. Add SMTP credentials in Settings → Email newsletter if you want member signups, password resets or newsletters to send. Ghost does not ship a mail server.
  4. Point your own domain at the app under Networking → Domains, then confirm the url variable matches it.

Frequently asked questions

What database does Ghost require — does it support PostgreSQL?

Ghost 5 requires MySQL 8 for production. PostgreSQL is not supported. SQLite is supported only for local development and is not recommended for a live site, so a self-hosted Ghost deployment needs a MySQL 8 service alongside the app container.

What is the minimal docker-compose.yml for Ghost?

Two services: ghost:5-alpine with port 2368 published, a volume at /var/lib/ghost/content, and the url plus database__client, database__connection__host, __user, __password and __database variables; and a mysql:8 service with its own volume at /var/lib/mysql. The full file is in the section above.

Where does Ghost store images and themes in Docker?

In /var/lib/ghost/content. That directory holds uploaded images, installed themes, custom adapters and the logs. Posts, pages, members and settings live in MySQL. Both the volume and the database have to be persisted and backed up together.

What does the Ghost url environment variable do?

It is the canonical public address of the blog and is mandatory. Ghost writes it into generated links, the sitemap, the RSS feed and email templates. If it does not match the address readers use, the site loads but links and redirects point at the wrong host.

How do I access the Ghost admin panel?

Add /ghost to the site URL, for example https://example.com/ghost. The first visit asks you to create the owner account. Create it right after the first deploy, because until it exists the setup screen is open to anyone who reaches the URL.

Does Ghost need an email provider?

Yes, for anything that sends mail. Member signups, password resets and staff invitations need SMTP, and bulk newsletter sending is built around Mailgun. Ghost runs fine without mail configured, but those features stay unavailable until credentials are set.

How do I back up a self-hosted Ghost blog?

Take a mysqldump of the Ghost database and copy the /var/lib/ghost/content volume. Ghost also has an export in Settings that produces a JSON file of posts and settings, but that export does not include uploaded images, so the volume copy is still needed.

How do I update Ghost in Docker?

Run docker compose pull and then docker compose up -d to move to the newest ghost:5-alpine image; the database migration runs on boot. On Hostim, redeploy the app. Back up the database first — Ghost migrations are not reversible.


Alternatives

  • WordPress — larger plugin ecosystem, heavier stack
  • Write.as / WriteFreely — minimal federated blogging
  • Hugo / Docusaurus — static sites with no database at all

Source + Docs


Looking for something else? Browse all templates →


Try it now

Deploy Ghost Now – in less than 60 seconds