← All articles
CONTENT MANAGEMENT Self-Hosting Ghost CMS: A Modern Blog Platform You A... 2026-02-09 · ghost · cms · blog

Self-Hosting Ghost CMS: A Modern Blog Platform You Actually Own

Content Management 2026-02-09 ghost cms blog newsletter publishing

WordPress powers 40% of the web, but most of that is plugins fighting with plugins, a dashboard from 2005, and a constant stream of security patches. If all you want is a clean, fast blog with optional newsletters and memberships, WordPress is overkill in the worst way.

Ghost is a publishing platform built for writers. It's Node.js under the hood, has a beautiful editor, supports newsletters natively, and can handle memberships and paid subscriptions without a single plugin. Self-hosting Ghost gives you the full feature set for free — the managed Ghost(Pro) service starts at $9/month.

What Ghost Does Well

The trade-off: Ghost's theme system is more constrained than WordPress. You get a curated set of capabilities rather than an infinite plugin ecosystem. For most blogs, this is a feature, not a bug.

Architecture

Caddy / Nginx HTTPS termination proxy Ghost Publishing platform Admin UI + Content API Newsletter engine MySQL Content storage SMTP Server Newsletters & transactional email Content Volume Images & themes Readers

Docker Deployment

# docker-compose.yml
services:
  ghost:
    image: ghost:5
    ports:
      - "2368:2368"
    volumes:
      - ghost_content:/var/lib/ghost/content
    environment:
      url: https://blog.yourdomain.com
      database__client: mysql
      database__connection__host: db
      database__connection__user: ghost
      database__connection__password: ghostdbpass
      database__connection__database: ghost
      mail__transport: SMTP
      mail__options__host: smtp.mailgun.org
      mail__options__port: 587
      mail__options__auth__user: [email protected]
      mail__options__auth__pass: your-smtp-password
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: mysql:8.0
    volumes:
      - ghost_db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_USER: ghost
      MYSQL_PASSWORD: ghostdbpass
      MYSQL_DATABASE: ghost
    restart: unless-stopped

volumes:
  ghost_content:
  ghost_db:
docker compose up -d

Ghost is now running at http://your-server:2368. Visit http://your-server:2368/ghost to set up your admin account.

Critical: The url environment variable must match the actual URL you'll serve Ghost from. If this is wrong, links, images, and the admin panel will break.

Initial Setup

  1. Navigate to https://blog.yourdomain.com/ghost
  2. Create your admin account (first user becomes the owner)
  3. Set your site title, description, and upload a logo
  4. Write your first post using the block-based editor

The editor supports markdown shortcuts (type ## for a heading, > for a blockquote), drag-and-drop images, embedded bookmarks, code blocks with syntax highlighting, and content cards for galleries, buttons, and callouts.

Email Newsletter Configuration

Ghost can send your posts directly to subscriber inboxes. This is one of its strongest self-hosted features.

For self-hosted Ghost, you need an SMTP provider. Good options:

Provider Free tier Cost after
Mailgun 1,000 emails/month $0.80/1,000
Amazon SES 3,000/month (if sending from EC2) $0.10/1,000
Brevo (Sendinblue) 300 emails/day $25/month for 20K
Postmark 100 emails/month $1.25/1,000

Configure the SMTP settings in your environment variables (shown in the Docker Compose above), then enable newsletters in Settings > Email newsletter.

Memberships and Subscriptions

Ghost supports free and paid memberships with Stripe integration:

  1. Go to Settings > Membership
  2. Connect your Stripe account
  3. Set pricing for paid tiers
  4. Create member-only content by toggling post visibility

This gives you a full Substack-like publishing platform — but you own everything. Your subscriber list, your content, your revenue. No platform taking a cut.

Theme Customization

Ghost uses Handlebars templates. The default theme (Casper) is clean and responsive, but the community has dozens of free and premium themes.

# Install a theme from a zip file
# Upload via Ghost Admin > Settings > Design > Change theme

# Or mount a custom theme directory
# Add to docker-compose volumes:
# - ./my-theme:/var/lib/ghost/content/themes/my-theme

For light customization, Ghost's code injection feature lets you add custom CSS and JavaScript without editing theme files:

Go to Settings > Code injection and add custom styles:

<style>
  .gh-content {
    font-family: 'Georgia', serif;
    max-width: 720px;
  }
</style>

Using Ghost as a Headless CMS

Ghost's Content API lets you use any frontend framework while Ghost manages your content:

const response = await fetch(
  'https://blog.yourdomain.com/ghost/api/content/posts/?key=your-content-api-key'
);
const { posts } = await response.json();

This works well with Next.js, Astro, Gatsby, or any static site generator. You get Ghost's excellent editor for content creation while having full control over the frontend.

Ghost vs WordPress vs Hugo

Feature Ghost WordPress Hugo
Built-in newsletters Yes Plugin required No
Memberships Yes Plugin required No
Editor quality Excellent Adequate Text editor
Plugin ecosystem Small Massive N/A
Performance Fast Varies wildly Static (fastest)
Security surface Small Large (plugins) Minimal (static)
RAM usage ~150 MB ~200+ MB Build-time only
Learning curve Low Medium Medium
Self-host complexity Easy Easy Easy (but different)

Backup Strategy

Ghost stores content in MySQL and files (images, themes) in the content directory. Back up both:

# Database backup
docker exec ghost-db-1 mysqldump -u ghost -pghostdbpass ghost > ghost-backup.sql

# Content backup (images, themes)
docker cp ghost-ghost-1:/var/lib/ghost/content ./ghost-content-backup

Ghost also has a built-in export feature: Settings > Labs > Export generates a JSON file with all your content (but not images).

The Bottom Line

Ghost is the best self-hosted option for writers who want a modern publishing platform without the complexity of WordPress. The built-in newsletter and membership features mean you can run a complete Substack alternative on your own infrastructure. Deploy it with Docker, point a reverse proxy at it, configure SMTP for newsletters, and you have a professional publishing platform that you fully control.