shouldiselfhost?they tell you if you can — we tell you if you should
THE DECISION LAYER FOR SELF-HOSTING100 APPS UNDER COVERAGEPROTOCOL v1NO VENDOR HAS EVER PAID FOR A RATING
§
MARKETING-CONTENT
Ghost(Pro) logo

Should I self-host Ghost(Pro)?

$18/mo · Starter · alternative: Ghost
RATING
YES
OUTLOOK
NOT ASSIGNED
RATIONALE

It's the same Ghost. $18/mo buys hosting, email infrastructure and zero ops — $216/yr buys a lot of newsletters, and the software is right there.

WHAT YOU LOSE
01

Ghost(Pro)'s bundled newsletter deliverability — bring Mailgun for bulk sends

02

Automatic upgrades from the people who wrote it (and fund it — Pro revenue pays for the software you're running)

WHAT YOU'RE PAYING FOR

publishing/blog · newsletter sending · memberships/paid subs · themes

Self-Hosting Facts
1 app per panel · Ghost(Pro)
Assumes 1 seat on 1 always-on box you already run
Amount per month% of sub *
Subscription$18.00
VPS share1.508%
Storage + backup0.000%
Your hours · 20 min @ $206.6737%
Self-hosted all-in8.1745%
Effective markup2.2×
Setup · 50 min measured$16.67 once
Break-even1.7 months
VERDICT
YES
OUTLOOK
NOT ASSIGNED

* Percent of the subscription price. Your time is priced at the slider's rate — $0/h ("my homelab time is free and I love it") is a legitimate position. Every number is derived from the record, never hand-written. Price source, checked 2026-08-05.

Runs comfortably on a real VPS (2 GB+).

01
ALTERNATIVES
Ranked alternatives
01Ghost logo
GhostThe same publishing platform Ghost(Pro) hosts, on your own box, with the editor, the themes and the members list intact.
TryGhost/Ghost · ★ 54,736 · 0d
Ghost running from the boot-verified compose file
Ghost, running from the compose file on this page — screenshot from our verified instance, not marketing material.
02
EVIDENCE
PROTOCOL
v1
VERIFIED BY
zernonia
REVIEWED
10 AUG 2026
SETUP MEASURED
50 MIN
AI ASSISTANT
CLAUDE-CODE · STATED
WHAT BROKE
01

Where IPv6 is disabled Ghost dies with the deeply unhelpful 'Code: -97' — it's EAFNOSUPPORT; set server__host: 0.0.0.0

02

MySQL 8's first-boot init answers socket pings while TCP is still down, so a socket-based healthcheck releases Ghost too early into an ECONNREFUSED crash-loop — probe with --protocol=tcp

03

Ghost 5 requires MySQL 8 specifically — SQLite and MariaDB are not supported paths

THE TESTED COMPOSE FILE — CI-BOOTED WEEKLY
# Ghost — the same software Ghost(Pro) hosts for $18/mo (Starter)
services:
  ghost:
    image: ghost:5-alpine
    container_name: ghost
    restart: unless-stopped
    depends_on:
      ghost-db:
        condition: service_healthy
    environment:
      url: http://localhost:2368
      # Ghost exits with cryptic "Code: -97" (EAFNOSUPPORT) where IPv6 is disabled; bind IPv4.
      server__host: 0.0.0.0
      database__client: mysql
      database__connection__host: ghost-db
      database__connection__user: ghost
      database__connection__password: ghost
      database__connection__database: ghost
    ports:
      - "2368:2368"
    volumes:
      - ghost-content:/var/lib/ghost/content
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:2368 >/dev/null || exit 1"]
      interval: 5s
      timeout: 5s
      retries: 36
      start_period: 30s

  ghost-db:
    image: mysql:8
    restart: unless-stopped
    environment:
      MYSQL_USER: ghost
      MYSQL_PASSWORD: ghost
      MYSQL_DATABASE: ghost
      MYSQL_ROOT_PASSWORD: root-changeme # throwaway test value
    volumes:
      - ghost-db:/var/lib/mysql
    healthcheck:
      # Must probe over TCP: during first-boot initialization MySQL runs a temp server that
      # answers the *socket* ping while port 3306 is still down — a socket-based check lets
      # dependents start too early and crash-loop on ECONNREFUSED.
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--protocol=tcp", "-ughost", "-pghost"]
      interval: 5s
      timeout: 5s
      retries: 36
      start_period: 30s

volumes:
  ghost-content:
  ghost-db:

Want a guided install instead? caniselfhostit.com/ghost-pro has AI-agent prompts that assume a bare machine — that's their half of the stool, and it's good.

FULL TIMED LOG
# Timed setup log: Ghost(Pro) → ghost

**Protocol:** v1 · **Verified by:** zernonia · **Date:** 2026-08-10
**Assistant:** claude-code · **Environment:** containerized runner, 2 vCPU class, Docker 29.3 / Compose v5.1

## Timeline

| Step | Time |
|---|---|
| Read upstream docs, draft compose with healthcheck | ~16 min |
| **Boot: all services healthy in 22 s (measured, `compose up --wait`)** | — |
| Endpoint-level workflow check (login/health/API serve) + re-run from clean volumes | ~16 min |
| **Total: ~50 min** | |

Boot and endpoint checks are machine-verified; `setup_min` is the wall-clock total for this
session including authoring, diagnosis and re-runs. Endpoint-level ≠ full human UI workflow —
dispute anything that doesn't reproduce (CONTRIBUTING.md).

## What broke

- Where IPv6 is disabled Ghost dies with the deeply unhelpful 'Code: -97' — it's EAFNOSUPPORT; set server__host: 0.0.0.0
- MySQL 8's first-boot init answers socket pings while TCP is still down, so a socket-based healthcheck releases Ghost too early into an ECONNREFUSED crash-loop — probe with --protocol=tcp
- Ghost 5 requires MySQL 8 specifically — SQLite and MariaDB are not supported paths

## Verdict-relevant notes

- Memberships + Stripe work self-hosted; bulk newsletter needs a Mailgun key.
03
HISTORY
10 AUG 2026UNRATED → YESInitial verdict: It's the same Ghost. $18/mo buys hosting, email infrastructure and zero ops.