Ghost
Professional publishing platform for blogs and newsletters
Ghost is a powerful open-source publishing platform built on Node.js, designed for professional bloggers, publications, and creators. It includes native membership, subscription, and email newsletter features alongside a fast, modern editor.
Key features
- Built-in membership and paid subscriptions
- Native email newsletters
- Fast modern editor
- SEO-optimized by default
Pros & cons
Strengths
- Excellent for newsletters and memberships
- Clean, fast publishing experience
Trade-offs
- Plugin ecosystem smaller than WordPress
- MySQL recommended for production
Ghost replaces
Last reviewed Aug 26, 2026 · 956 words
Substack keeps 10% of every paid subscription. Ghost(Pro) starts at about $9 a month. Self-hosted Ghost keeps 0%, and costs a $5 VPS plus Stripe's processing fee. That arithmetic is the reason to run it yourself, and three facts follow immediately: production Ghost requires MySQL 8, newsletters go out through Mailgun and nothing else, and the WordPress plugin culture does not exist here. If you write, sell memberships, and want to own your list, Ghost is the best tool in the CMS category. If you need a shop, a forum, or 40 plugins, it is the wrong one.
MySQL 8 is a requirement, not a recommendation
The catalogue phrases it as "MySQL recommended for production". Ghost's own documentation is firmer: since Ghost 5, MySQL 8 is the only supported production database, and SQLite works only when NODE_ENV=development. The distinction matters when you file a bug, because the first reply will ask which database you run. So the compose file has two services from day one:
services:
ghost:
image: ghost:alpine
ports:
- "2368:2368"
environment:
url: https://blog.example.com
database__client: mysql
database__connection__host: db
database__connection__user: ghost
database__connection__password: ghostpass
database__connection__database: ghost
mail__transport: SMTP
mail__options__host: smtp.example.com
mail__options__port: 587
mail__options__auth__user: [email protected]
mail__options__auth__pass: secret
volumes:
- ./content:/var/lib/ghost/content
depends_on:
- db
restart: unless-stopped
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: ghost
MYSQL_USER: ghost
MYSQL_PASSWORD: ghostpass
volumes:
- ./mysql:/var/lib/mysql
restart: unless-stopped
Pin ghost:alpine to a major-version tag before deploying, and change every password. The url value has to be the exact public address including https://, or the admin at /ghost/ loops on redirect behind a reverse proxy. The double-underscore keys are Ghost's way of expressing nested JSON config as environment variables; anything in config.production.json can be set this way. The first visit to /ghost/ creates the owner account, and 1 GB of RAM (the catalogue figure) is comfortable for a site doing tens of thousands of views a day.
Transactional mail is SMTP; newsletters are Mailgun, full stop
Ghost has two mail paths and they do not share a setting. Signup links, password resets, and staff invites go through whatever SMTP you put in mail__*; any provider works, and so does a Postfix relay. Bulk newsletters are different: the sending engine is built for Mailgun's batch API, and you configure it in Settings under Email newsletter with a Mailgun domain and API key. There is no supported way to swap in another bulk provider. Mailgun's pay-as-you-go tier is cheap at a few thousand subscribers, and a sending domain with SPF and DKIM set up takes 20 minutes. Do not be tempted to run the bulk mail through your own mail server; the honest take on self-hosted email explains why 2,000 identical messages from a fresh IP end in spam folders.
Memberships and Stripe: 0% platform fee, one connection
Settings, Membership, Connect with Stripe walks you through Stripe Connect, after which you define free and paid tiers, monthly and yearly prices, and Ghost registers the webhooks with Stripe on its own. Two requirements trip people: the site must be publicly reachable over HTTPS so Stripe can deliver webhook events, and the url must be final, because changing it later means reconnecting. Members log in by magic link (that is the transactional mail path above), and the portal, paywalled sections, and comments all come built in. On Ghost(Pro) this is the same code; the only difference on your own server is that the fee column reads zero.
Themes replace plugins, and Code Injection replaces most of the rest
A Ghost site is a Handlebars theme uploaded as a zip. The bundled theme is called Source, the theme marketplace has a few dozen free and paid options, and editing a theme is a text editor and zip -r. What WordPress does with plugins, Ghost does with three things: theme code, Settings under Code Injection (site-wide header and footer snippets, where a Plausible tag or a font import goes), and Integrations, which issue Content API and Admin API keys plus outbound webhooks. The catalogue's "smaller plugin ecosystem" con is polite; there is no plugin ecosystem, by design, and the site is faster and less hackable for it. If your publication needs event calendars, LMS features, or WooCommerce, WordPress remains the right call.
Upgrades are a tag bump if you back up first
Everything mutable is in ./content (images, themes, settings, any SQLite file) and the MySQL volume. Back up both, bump the image tag, docker compose pull && docker compose up -d, and Ghost runs its schema migrations on start. Across a major version, go to the last release of the current major first, then jump; the migrations assume that path. Ghost is 13 years old, MIT-licensed, funded by its own hosting business rather than venture money, and releases weekly, so a monthly upgrade habit keeps you close enough.
What I'd do
The compose file above on a $5 to $10 VPS with 2 GB of RAM, Caddy in front for TLS, a Mailgun domain configured the same afternoon if newsletters are the plan, and Stripe connected once the domain is final. Nightly mysqldump plus a tarball of content/, shipped off the box. Then write. A single author with 1,000 paid subscribers at $5 a month grosses $60,000 a year; after Stripe's roughly 2.9% plus 30 cents per charge that is about $54,600 on self-hosted Ghost against about $48,600 on Substack, and the $6,000 gap pays for the VPS about 50 times over.
Compare Ghost
21 head-to-head comparisons.
- Ghost vs Wagtail
- Ghost vs Grav
- Ghost vs October CMS
- Ghost vs Orchard Core
- Ghost vs Pagekit
- Ghost vs Statamic
- Ghost vs Mezzanine
- Ghost vs Pico
- Ghost vs Craft CMS
- Ghost vs Microweber
- Ghost vs Anchor CMS
- Ghost vs Piranha CMS
- Ghost vs PublicCMS
- Ghost vs Kirby
- Ghost vs Winter CMS
- Ghost vs Bludit
- Ghost vs MODX Revolution
- Ghost vs Fork CMS
- Ghost vs ProcessWire
- Ghost vs Backdrop CMS
- Ghost vs Automad
Similar content management systems apps
Payload CMS
Content Management SystemsTypeScript-native headless CMS and application framework
Replaces Contentful, Sanity
Docsify
Content Management SystemsDocumentation site generator
Replaces GitBook
WordPress
Content Management SystemsThe most popular content management system in the world
Replaces Wix, Squarespace
Wagtail
Content Management SystemsDeveloper-friendly Django CMS with a great editor experience
Replaces Adobe Experience Manager, WordPress
Grav
Content Management SystemsFast flat-file CMS with no database required
Replaces WordPress, Squarespace
Tina CMS
Content Management SystemsGit-backed content management with visual editing
Replaces Contentful, Sanity