Skip to content

jevellangelo/ghost-blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Ghost on Docker with Traefik

A minimal, production-ready setup for self-hosting Ghost in Docker behind Traefik with automatic TLS via Cloudflare DNS-01 challenges.

Stack

  • Ghost 5 (Alpine) — the blog platform
  • MySQL 8 — Ghost's recommended database for production
  • Traefik — reverse proxy, TLS termination, HTTP→HTTPS redirect
  • Cloudflare — DNS provider / wildcard cert resolver

Prerequisites

  • A VPS with Docker and Docker Compose installed
  • Traefik already running and attached to an external Docker network (e.g. traefik-network)
  • A domain with DNS managed by Cloudflare
  • A Cloudflare API token configured as your Traefik certresolver
  • A DNS A record pointing ghost.yourdomain.com to your VPS IP

Setup

1. Clone the repo

git clone https://github.com/yourusername/ghost-docker-traefik.git
cd ghost-docker-traefik

2. Create your .env file

cp .env.example .env

Edit .env and fill in:

  • MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD — generate with openssl rand -hex 32
  • SMTP_HOST, SMTP_PORT, MAIL_FROM — point at your mail relay
  • SMTP_USER / SMTP_PASS — leave blank if your relay uses IP allowlisting

3. Update docker-compose.yml

Replace all occurrences of yourdomain.com and ghost.yourdomain.com with your actual domain and subdomain:

sed -i 's/yourdomain.com/example.com/g' docker-compose.yml
sed -i 's/ghost.yourdomain.com/ghost.example.com/g' docker-compose.yml

Also update the url environment variable under the ghost service to match.

4. Update the Traefik network name

If your Traefik external network is named something other than traefik-network, update it in the networks section at the bottom of docker-compose.yml.

5. Deploy

docker compose up -d
docker compose logs ghost -f

Wait for:

Ghost is running in production...
Your site is now available on https://ghost.yourdomain.com/

6. Create your admin account

Go to https://ghost.yourdomain.com/ghost and complete the setup wizard. Do this immediately — the wizard is open to anyone until finished.

Architecture

Internet
    │
    ▼
Traefik (:443)
    │  TLS terminated, cert via Cloudflare DNS-01
    ▼
Ghost container (:2368)
    │  traefik-network (external overlay)
    ▼
MySQL container (:3306)
    │  ghost-internal network (internal — not reachable from outside)
  • MySQL is on ghost-internal, which has internal: true — it is not reachable from Traefik or the internet, only from the Ghost container.
  • The traefik.docker.network=traefik-network label tells Traefik which network interface to use when the Ghost container is on multiple networks. Without it, Traefik may try to route via the internal network and get a 504 gateway timeout.

Mail

Ghost uses SMTP for member notifications, newsletters, and password resets. The .env.example assumes a self-hosted relay on port 587 with STARTTLS. If your relay uses IP allowlisting rather than credentials, leave SMTP_USER and SMTP_PASS blank.

Volumes

Volume Contents
ghost-content Themes, images, and uploaded files
ghost-db-data MySQL data directory

Both are named Docker volumes — they persist across docker compose down and container rebuilds. To wipe and start fresh: docker compose down -v.

Installing the Solo theme

Ghost ships with the Source theme by default. To install the official Solo theme:

# Download on your server
curl -L https://github.com/TryGhost/Solo/releases/latest/download/solo.zip -o solo.zip

# Copy into the Ghost content volume
docker cp solo.zip ghost:/var/lib/ghost/content/themes/solo.zip
docker exec ghost sh -c "cd /var/lib/ghost/content/themes && unzip -o solo.zip -d solo && rm solo.zip"
docker restart ghost

Then activate it in Ghost Admin → Settings → Design → Change theme.

License

MIT

About

Ghost on Docker with Traefik

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors