Substack takes 10% of your subscription revenue and owns your email list. Beehiiv keeps changing pricing tiers. Medium decides what gets discovered. WordPress is a CMS pretending to be a publishing platform. Ghost is the modern publishing-first platform: built specifically for writers and newsletters, with Stripe-powered paid memberships, beautiful editor, native email delivery, and a tenth of WordPress's attack surface.
This guide installs Ghost on a Linux VPS using the official CLI, configures Nginx + Let's Encrypt for HTTPS, hooks Mailgun for email newsletter delivery, sets up Stripe for paid memberships, and walks through theme installation, backups, and the operational practices that keep a Ghost blog reliably online. By the end you'll own your publication outright — content, email list, payment relationships, all yours.
- A Linux VPS — Ubuntu 22.04 or Debian 12, 1 GB RAM minimum (2 GB recommended)
- A domain pointed at the VPS
- A Mailgun account (other Ghost-compatible providers also work)
- A Stripe account if you'll charge for memberships
- Roughly 30 minutes
For a Ghost VPS with Node.js LTS, MySQL, and Nginx pre-configured, see our Ghost VPS plans.
1. Ghost(Pro) vs self-hosted
Quick honesty about what you give up by self-hosting. Ghost(Pro) is the managed service from the Ghost foundation — same software, they handle the ops. Real differences:
| Ghost(Pro) | Self-hosted on VPS | |
|---|---|---|
| Starting price | $9–11/mo (1k subs) | $7.99/mo flat (any subs) |
| Email included | Yes (capped per tier) | You pay Mailgun separately |
| Updates | Automatic | One CLI command |
| Backups | Automatic | You configure |
| SSL | Auto | Auto via the installer |
| Subscriber limit | 500 / 1k / 25k by tier | Unlimited |
| Custom integrations | Limited to public APIs | Full Node.js access |
| Funds Ghost development | Yes (~$2M/yr in revenue) | No |
Self-hosting wins at scale (25k subscribers on Ghost(Pro) is $199/mo; same on your VPS is still $7.99/mo + Mailgun). Self-hosting also wins for technical customization. Ghost(Pro) wins on convenience and supports the project. Pick accordingly.
2. Prepare the VPS
apt update && apt upgrade -y
apt install -y curl ca-certificates ufw
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
# Non-root user for Ghost
adduser ghost-mgr
usermod -aG sudo ghost-mgr
rsync --archive --chown=ghost-mgr:ghost-mgr ~/.ssh /home/ghost-mgr
3. Install Node.js + MySQL
Ghost needs Node.js (currently 18 or 20 LTS) and MySQL 8.
# Node.js 20 LTS via NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
# MySQL 8
apt install -y mysql-server
# Set the root password and lock down defaults
mysql_secure_installation
# Answer: Y, set a strong password, Y to everything else
# Nginx
apt install -y nginx
# Ghost CLI (the official installer)
npm install -g ghost-cli@latest
Verify versions:
node --version # should be v20.x
mysql --version # should be 8.x
ghost --version
4. Run ghost-cli install
Switch to the ghost-mgr user (Ghost refuses to install as root) and create the install directory:
su - ghost-mgr
sudo mkdir -p /var/www/ghost
sudo chown ghost-mgr:ghost-mgr /var/www/ghost
sudo chmod 775 /var/www/ghost
cd /var/www/ghost
ghost install
The interactive installer asks:
- Blog URL:
https://writing.example.com - MySQL hostname:
localhost - MySQL username:
root(it'll prompt for the password you set above) - Set up a Ghost MySQL user?: yes (it creates a dedicated DB user)
- Set up Nginx?: yes
- Set up SSL?: yes (Let's Encrypt cert provisioned automatically — needs DNS already pointing at the VPS)
- Set up systemd?: yes
- Start Ghost?: yes
The installer downloads Ghost, sets up MySQL, configures Nginx, requests an SSL cert, creates a systemd service, and starts the application. Total time: ~3 minutes.
When it finishes, visit https://writing.example.com/ghost — this is the admin panel. Sign up — first account becomes admin. From there, write your first post, click Publish, and you have a working blog.
5. Wire up Mailgun for newsletters
The newsletter feature is Ghost's killer feature — same software publishes to web AND email simultaneously. But Ghost doesn't send email itself; it hands off to a bulk-email provider.
Ghost officially supports Mailgun as the bulk-email provider. (Other providers — Postmark, SendGrid — work for transactional email but not newsletter delivery.)
- Sign up at mailgun.com, verify your sending domain (add SPF, DKIM DNS records — Mailgun walks you through it)
- Pick the EU or US region in Mailgun
- In Ghost admin: Settings → Email newsletter → Mailgun config
- Paste the Mailgun API key and Domain. Pick the matching region.
- Save.
Test send: write a draft post, click Publish & send, send to "Test email" first. If you receive it, you're live. If not, check Mailgun's logs — usually a DNS misconfig.
Mailgun costs at scale: ~$15/mo for 10k email sends. A weekly newsletter to 2.5k subscribers = ~10k sends/month = $15. Above 100k subscribers, switch to Mailgun's enterprise tier or migrate to Amazon SES.
6. Stripe memberships
Membership and paid subscription is built into Ghost. Connect Stripe:
- In Ghost admin: Settings → Membership → Connect with Stripe
- Sign in to Stripe, authorize the connection
- Define your tiers: free (no payment), monthly, yearly. Set prices.
- Customize signup form copy, post-signup email template
Ghost charges no platform fee. Stripe's standard fees apply (2.9% + $0.30 in the US, variable elsewhere). If you charge $5/mo for membership, you net ~$4.55 — vs Substack which takes 10% PLUS Stripe fees and leaves you with $4.05.
Restricting content to paid members: in the post editor, Post settings → Visibility → select "Members only" or "Paid members only". Free preview length and call-to-action are configurable.
🐾 Ghost-tuned hosting
Our Ghost VPS plans ship with Node.js LTS, MySQL 8, Nginx, and SMTP integration ready to fill in. Same hardware (NVMe, real cores), 25 minutes of install saved.
See Ghost VPS Plans →7. Install a theme
Ghost's default Source theme is excellent and is what most premium publications use. To switch:
In admin: Settings → Theme → browse the marketplace or click Upload theme to install a ZIP. The Ghost marketplace at ghost.org/themes/ has both free and premium themes.
For custom theme development, themes are zipped Handlebars + CSS bundles. Download Source as a starting point, modify, re-upload. Ghost's theme docs at ghost.org/docs/themes/ are excellent.
Popular themes worth looking at: Source (default, free), Casper (legacy default, free), Edition (newsletter-focused, free), Solo (single-author, free).
8. Backups and updates
Ghost's CLI handles updates trivially:
cd /var/www/ghost
ghost update
This pulls the new version, runs migrations, restarts the service. Total downtime: ~10 seconds. Run after major release announcements at ghost.org/changelog.
Backups: Ghost has an export tool in the admin panel (Settings → Labs → Export) but it only exports content as JSON — no images, no theme files, no MySQL state.
Real backup script:
cat > /home/ghost-mgr/backup-ghost.sh <<'EOF'
#!/bin/bash
set -euo pipefail
TS=$(date +%Y%m%d-%H%M%S)
DEST=/home/ghost-mgr/backups
mkdir -p "$DEST"
# Database
mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" ghost_production | gzip > "$DEST/ghost-db-$TS.sql.gz"
# Content directory (images, files, themes)
tar -czf "$DEST/ghost-content-$TS.tar.gz" -C /var/www/ghost content
# Retention: keep 30 days
find "$DEST" -name '*.gz' -mtime +30 -delete
EOF
chmod +x /home/ghost-mgr/backup-ghost.sh
# Cron daily at 3 AM
crontab -e
# Add (use environment variables or .my.cnf for the MySQL password):
# 0 3 * * * /home/ghost-mgr/backup-ghost.sh >> /home/ghost-mgr/backup.log 2>&1
Push backups off-VPS — rclone to Backblaze B2 / S3 / Wasabi. Test restore once a month.
9. Reference: scaling, integrations
Scaling capacity
| Plan | Subscribers | Monthly pageviews | Notes |
|---|---|---|---|
| Starter ($7.99, 1 GB) | Up to ~1,000 | ~50k | Solo blog, light traffic |
| Pro ($15.99, 4 GB) | Up to ~10,000 | ~500k | Sweet spot for indie creators |
| Premium ($35.99, 8 GB) | 50,000+ | ~5M | Pro publications, multi-author |
Ghost vs WordPress
Ghost is faster, cleaner, and built specifically for publishing + memberships. WordPress is vastly more flexible (60,000 plugins) and has a much larger talent pool. Pick Ghost if you write content and sell subscriptions. Pick WordPress if you need WooCommerce, custom plugins, or maximum theme freedom.
Custom integrations
Ghost has webhooks, REST API, and a JS SDK. Common integrations:
- Discord/Slack notifications on new posts (webhook → channel message)
- Mailgun statistics dashboard — pull open/click rates back into your analytics
- Algolia or Meilisearch for full-text search (Ghost's native search works but is basic)
- Comments via Cusdis or Disqus — Ghost has no built-in comments
Migration from Substack / Beehiiv / Medium
Ghost has an official Substack importer. Pulls posts, subscribers (free and paid), and comments. Subscriber payment data needs Stripe migration (Substack uses Stripe under the hood; transfer the customer list to your Stripe account). Plan: 30 minutes for the technical import, 2 weeks to migrate paid subs (you'll need to ask subscribers to confirm they want to continue).
Comments
Ghost has native comments (released 2023) for paid members. If you want broader commenting (free users too), the native system supports that. For external commenting systems: Cusdis (self-hosted, free), Disqus (third-party, free, ad-supported), Hyvor Talk (paid, no ads).
Search
Ghost has built-in search (introduced in 5.x) — works fine for small-to-medium content libraries. For ~500+ posts, pair with Algolia (Ghost integration available) or self-hosted Meilisearch for better relevance ranking.
FAQ
Why Ghost instead of WordPress for blogging?
Ghost was built specifically for publishing + newsletters + memberships. WordPress is a CMS that does blogging adequately. Ghost has faster page loads, native newsletter delivery, native Stripe memberships, cleaner editor, better SEO defaults. WordPress wins if you need WooCommerce, complex plugins, or specific themes only available there. For 90% of blogs and newsletter publications, Ghost is the better choice.
Does Ghost work without Mailgun?
The blog works fully. Newsletter sending requires a bulk-email provider — and Ghost's CLI configuration assumes Mailgun. You CAN configure other providers manually by editing the config, but it's fiddly and Ghost's support assumes Mailgun. For 99% of self-hosters, just use Mailgun.
Can I import from Substack?
Yes — Ghost has an official Substack importer that handles posts, free subscribers, and paid subscribers. Subscriber payment data needs Stripe migration (both Substack and Ghost use Stripe; you migrate the customer list). The technical migration takes 30 minutes; the customer-communication migration (asking paid subs to confirm) takes 2 weeks.
How much does it cost to send a newsletter to 10,000 subscribers?
Mailgun pricing as of 2026: 10,000 monthly email sends = ~$15. A weekly newsletter to 10k subscribers = 40k sends = ~$50/mo. At 50k subscribers, Mailgun is ~$150/mo. Compare to Ghost(Pro)'s Creator tier at $199/mo for 1k subs (yes, that's their pricing) — self-hosting saves dramatically at scale.
Can I run Ghost on the 1 GB Starter plan?
Yes, but it's tight. Ghost wants ~400 MB RAM idle, plus 200 MB for MySQL, plus another ~200 MB for Nginx + system. The Starter handles solo blogs (~500 subscribers, ~10k monthly pageviews) fine. For anything bigger, Pro ($15.99, 4 GB) is the realistic minimum.
Does Ghost have a mobile admin app?
Not currently. The admin UI is mobile-responsive in the browser (you can write posts from your phone), but there's no native iOS or Android admin app. For writing on the go, the web editor on iPad with a Bluetooth keyboard is the standard workflow.