Jesse A. Green / notebook

Ghost User Guide

Generated June 2026 from TryGhost/Ghost at f283e8e

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Ghost is the professional publishing platform — an open source application for running independent publications: blogs, newsletters, magazines, and paid-membership websites. A single Ghost install gives you a writing and editing studio, a public website, a built-in email newsletter engine, native paid subscriptions (via Stripe), member management, comments, search, and web analytics, all from one admin panel.

This guide is written for the people who run and use a Ghost publication — writers, editors, publishers, and site owners. It covers getting Ghost running, every part of the admin experience, and the day-to-day workflows of publishing. Architecture, configuration internals, deployment, and security hardening live in the companion Admin Guide, which this guide links to where appropriate.

Note

Ghost is produced by the Ghost Foundation and is licensed under the MIT License. It is a pnpm + Nx monorepo built on Node.js ^22.13.1. The default site runs at http://localhost:2368/ with the admin panel at http://localhost:2368/ghost/.


Table of Contents

  1. What Ghost Is
  2. Quick Start
  3. Installation
  4. The Admin Panel
  5. Writing & Publishing Content
  6. Members & Subscriptions
  7. Email Newsletters
  8. Themes & Site Design
  9. Comments, Search & Engagement Widgets
  10. Analytics & Stats
  11. Integrations, APIs & Webhooks
  12. Staff, Roles & Settings
  13. Importing, Exporting & Backups
  14. Developer & Maintenance Commands
  15. Troubleshooting
  16. Frequently Asked Questions
  17. Reference Tables

1. What Ghost Is

Ghost is a self-hostable, headless-capable publishing system. Out of the box, a single deployment provides:

  • A public website rendered from a Handlebars-based theme, with posts, pages, tags, author pages, an RSS feed, a sitemap, and structured metadata.
  • An editor (the "Koenig" editor) for writing rich posts with cards — images, galleries, bookmarks, embeds, HTML, markdown, buttons, callouts, and more.
  • A members system that lets readers sign up for free or paid accounts, gated behind tiers you define.
  • Native payments through Stripe, supporting monthly/yearly subscriptions, one-time tips & donations, and gift subscriptions.
  • An email newsletter engine that turns any post into an email sent to your members, with per-newsletter design and open/click analytics.
  • Engagement widgets — a member Portal, Comments, Search (sodo-search), a Signup form, and an Announcement bar — all delivered as lightweight scripts.
  • Web analytics powered by a Tinybird-based traffic pipeline, plus member growth and email performance stats.
  • A full REST API (a public Content API and an authenticated Admin API), webhooks, and custom integrations.

Tip

Ghost separates the application (this repository) from your theme and your content. Your writing, images, members, and settings live in a database and a content/ directory; your site's look is controlled by an independent theme. This separation is what makes upgrades safe and themes swappable.

The pieces of a running Ghost site

Piece What it is Where you see it
Site / frontend The public website readers visit http://your-site/
Admin The management studio http://your-site/ghost/
Portal The member signup / account popup Floating button + /#/portal on your site
Content & Admin API Programmatic access http://your-site/ghost/api/content/ and /ghost/api/admin/
Theme Handlebars templates controlling layout Uploaded under Settings → Design
Content folder Images, media, files, themes, logs, data content/ on the server

2. Quick Start

The fastest way to try Ghost on your own machine is the Docker-based development environment that ships in this repository. For a real, public publication you will instead use Ghost-CLI on a server (see Installation).

Important

The repository's pnpm dev flow is a development environment — it runs database services in Docker and frontend apps in watch mode. It is for evaluating, theming, and contributing, not for production hosting.

# 1. Clone the repository with submodules (themes are submodules)
git clone --recurse-submodules https://github.com/TryGhost/Ghost.git
cd Ghost

# 2. Enable the pinned package manager (pnpm) via corepack
corepack enable pnpm

# 3. Install dependencies and initialise submodules
pnpm run setup

# 4. Start the full development stack (Docker backend + frontend dev servers)
pnpm dev

Once boot completes, Ghost is reachable at:

Main site:   http://localhost:2368/
Admin panel: http://localhost:2368/ghost/

Visit http://localhost:2368/ghost/ and you will be guided through creating the first account (the Owner) and naming your site.

Note

The first run requires Docker and Docker Compose to be installed and running — Ghost's dev environment uses Docker for MySQL, Redis, Mailpit (email capture), and optional Tinybird analytics.

Seeding sample data (optional)

To explore the admin with realistic content, generate fake members and posts:

# 1,000 members and 100 posts, deterministic seed
pnpm reset:data
# Equivalent underlying command (runs inside the ghost-dev container):
node index.js generate-data --clear-database --quantities members:1000,posts:100 --seed 123

Other ready-made data sizes:

pnpm reset:data:empty   # clean database, no members or posts
pnpm reset:data:xxl     # 2,000,000 members (stress / scale testing)

Caution

reset:data commands include --clear-database, which deletes all existing data first. Never run them against a publication whose content you care about.


3. Installation

There are three meaningfully different ways to run Ghost. Pick the one that matches your goal.

Production (recommended)

Real, public Ghost sites are installed with Ghost-CLI (ghost), the official command-line installer. Ghost-CLI provisions the app, configures MySQL, sets up a system service, and manages SSL and upgrades. A typical install looks like:

# Install the CLI globally
npm install ghost-cli@latest -g

# Create an empty directory and install Ghost into it
mkdir ghost && cd ghost
ghost install

During ghost install you are prompted for your blog URL, MySQL connection details, an optional dedicated MySQL user, and whether to set up systemd and start Ghost. After install, manage the instance with:

ghost start      # start the instance
ghost stop       # stop the instance
ghost restart    # restart
ghost ls         # list installed instances
ghost update     # upgrade to the latest Ghost

Note

Ghost-CLI is a separate tool from this repository. The repository's CLI (node index.js …) is for development tasks like data generation, not production lifecycle management. See the Admin Guide for production system requirements and deployment topology.

Local development (this repo)

For theming, contributing, or evaluation, use the in-repo Docker dev stack described in Quick Start:

corepack enable pnpm
pnpm run setup
pnpm dev

Variants of pnpm dev enable optional services:

pnpm dev:sqlite     # use SQLite instead of MySQL
pnpm dev:mailgun    # wire up Mailgun for outbound email
pnpm dev:analytics  # start the Tinybird analytics stack
pnpm dev:storage    # start MinIO object storage
pnpm dev:stripe     # run with a local Stripe listener
pnpm dev:all        # analytics + storage + Stripe together

Docker Compose (manual)

The repository ships Compose profiles for running pieces independently. For example, to bring up the bundled analytics stack and a split Ghost service:

docker compose --profile analytics up -d
docker compose --profile split up

Ghost will be reachable at http://localhost:2368 with analytics working out of the box.

Requirements at a glance

Requirement Detail (from source)
Node.js ^22.13.1 (declared in engines)
Package manager pnpm@11.4.0 (pinned; enable with corepack enable pnpm)
Database MySQL 8 in production (mysql2 client); SQLite supported for development
Docker Required for the in-repo development environment
Default port 2368 (configurable via server.port)
Default URL http://localhost:2368

Tip

The default content directory is content/, which holds images/, media/, files/, themes/, adapters/, logs/, data/, settings/, and public/. Back this folder up along with your database — together they are your entire site.


4. The Admin Panel

The admin panel at /ghost/ is where everything is managed. The first account you create is the site Owner; you can invite additional staff later (see Staff, Roles & Settings).

The admin is organised into a left sidebar with the major areas of your publication:

Area What you do there
Dashboard / Analytics See member growth, email performance, and traffic at a glance
Posts Write, edit, schedule, and manage articles
Pages Manage standalone pages (About, Contact, etc.)
Tags Organise content and power dynamic collections
Members View, filter, and manage your audience
Stats Web analytics, sources, top content, member attribution
Settings Site identity, design, membership, newsletters, integrations, staff

Note

Ghost's admin is delivered as two layers: a long-standing Ember.js application (ghost/admin) and a newer set of React apps (apps/admin-x-settings, apps/posts, apps/stats, apps/activitypub, and shared design systems). As a user you experience these as one seamless interface; the split matters only to developers.

Onboarding

On first launch Ghost walks you through:

  1. Create your account — name, email, and password for the Owner.
  2. Name your site — the title shown across your website and emails.
  3. Choose how you'll use Ghost — publishing, newsletters, paid memberships, or a mix.

You can change every one of these choices later from Settings.


5. Writing & Publishing Content

Posts vs. Pages

Type Purpose Appears in feeds?
Post A dated article — the core unit of a publication Yes (RSS, archives, tags)
Page A standalone, typically static page (About, Contact) No

Both are written in the same editor; the difference is how Ghost lists and routes them.

The editor (Koenig)

Ghost's editor is a rich, block-based writer. You type prose normally and insert cards for richer content. Insert a card by typing / on a new line or clicking the + button.

Common cards include:

  • Image, Gallery, and Image with caption
  • Bookmark (rich link preview) and Embed (YouTube, X/Twitter, etc.)
  • Markdown and HTML for hand-authored blocks
  • Button, Callout, and Divider
  • Email call-to-action and Public/Members content toggles for gating
  • Product, Header, Audio, Video, and File cards

Tip

Cards that gate content (member-only segments) let a single post show different content to anonymous visitors, free members, and paid members. This is the foundation of "some posts free, some paid."

Post settings

Each post has a settings panel (the gear icon) where you control:

  • URL slug and publish date
  • Tags (the first tag is the "primary" tag, used by many themes)
  • Authors (posts can have multiple)
  • Feature image and excerpt
  • Meta data for SEO (title, description, canonical URL)
  • Social cards (Facebook/Open Graph and X/Twitter previews)
  • Post access — who can read it (public, members, paid members, or a specific tier)
  • Code injection — per-post header/footer snippets

Publishing & scheduling

When you click Publish, Ghost offers three outcomes:

  1. Publish — make it live on the website.
  2. Publish & email — make it live and send it as a newsletter to chosen recipients.
  3. Email only — send as a newsletter without adding it to the public site.

You can also schedule publication for a future time.

Note

Scheduling is handled by Ghost's internal scheduler (the default adapter is a pure-JavaScript implementation — no external cron required). There is a small tolerance window around scheduled times; posts cannot be scheduled to publish in the immediate past.

Warning

"Publish & email" and "Email only" send real email to your members the moment the post goes out. Use a test email (available from the publish flow) to preview rendering before sending to your whole list — email clients (especially Outlook) render differently from the web.


6. Members & Subscriptions

Ghost has a first-class members system: readers can create accounts, and you can charge them.

How membership works

  • Free members sign up with just an email (passwordless magic-link sign-in).
  • Paid members subscribe to a Tier you define, paying through Stripe.
  • Membership state controls content access per post and per newsletter.

Tiers

A Tier is a subscription product. Each tier has a name, description, benefits, and pricing (monthly and/or yearly). You can have a free tier and one or more paid tiers. Posts and newsletters can be restricted to specific tiers.

Connecting Stripe

Paid memberships require a Stripe account. In Settings → Membership you connect Stripe (via a secure connect flow). Once connected, Ghost can create checkout sessions, manage subscriptions, and react to Stripe events.

Important

Ghost listens for Stripe webhooks to keep subscriptions in sync — events like customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, invoice.payment_succeeded, and checkout.session.completed. These can arrive out of order or in parallel, so Ghost is designed to reconcile them idempotently. You do not configure these by hand — Ghost registers the webhook endpoint with Stripe for you.

The signup & checkout flow

Member clicks "Subscribe" in Portal
        │
        ▼
Portal asks Ghost to create a Stripe Checkout session
        │
        ▼
Member enters payment details on Stripe's secure page
        │
        ▼
Stripe redirects back + sends webhooks → Ghost upserts the member & subscription

Tips, donations & gifts

Beyond subscriptions, Ghost supports:

  • Tips & donations — one-time payments from readers (enabled by default; controlled by the enableTipsAndDonations setting).
  • Gift subscriptions — members can purchase a subscription for someone else.

Member attribution

Ghost automatically tracks how each member found you — which post or page they were reading, the referrer (Google, Facebook, etc.), and any UTM campaign parameters. This powers the "where are my members coming from?" reports.

Signup context Recorded source Recorded medium
Imported Imported Member Importer
Created in admin Created manually Ghost Admin
Created via API Created via API Admin API
Via an integration Integration: {name} Admin API

Tip

Source tracking can be turned off with the members_track_sources setting, and outbound newsletter link tagging with outbound_link_tagging, if you prefer not to track attribution.


7. Email Newsletters

Any post can become a newsletter. Ghost renders your post into an email and sends it to the members you target.

Newsletters

You can run multiple newsletters from one Ghost site (for example a free weekly and a paid deep-dive). Each newsletter has its own:

  • Name, description, and sender details
  • Design — header/footer, colours, fonts, feature image visibility, "latest posts" footer
  • Subscriber list (members opt in per newsletter)

Sending

When you choose Publish & email (or Email only), Ghost:

  1. Renders the post to email-safe HTML.
  2. Batches recipients (default batch size is 1,000 per batch) and hands them to your email provider.
  3. Tracks opens and clicks (when enabled) and feeds them into email analytics.

Note

Outbound bulk email requires a mail provider configured by your administrator (commonly Mailgun for bulk newsletters). Transactional email (magic links, staff invites) uses a separate transport. See the Admin Guide for mail configuration.

When click tracking is enabled, Ghost rewrites links in the email to a redirect of the form:

https://your-site/r/{hash}?m={member_uuid}

When a member clicks, Ghost records the click, updates the member's "last seen" timestamp, and then transparently redirects them to the real destination. This is what produces per-link click stats and re-engagement data.

Tip

A "golden post" containing one of every editor card is used internally to verify that newsletters render correctly across email clients. If a particular card looks wrong in your inbox, send a test email first and adjust — Outlook in particular is sensitive to complex layouts.


8. Themes & Site Design

Your site's appearance is controlled by a theme — a package of Handlebars templates, CSS, and JavaScript. Themes are independent of Ghost itself, so you can change your whole look without touching your content.

Default themes

Ghost ships with official themes maintained by the Ghost Foundation:

Theme Description Default posts_per_page
Source The current default theme 16
Casper The long-standing classic theme 25

Both require Ghost >= 5.0.0 and expose customisable settings (navigation layout, fonts, colour scheme, header style, feed layout, and more) that you edit visually in Settings → Design.

Customising design

In Settings → Design you can, without editing code:

  • Set your brand colour, logo, icon, and publication cover
  • Choose fonts and colour scheme (where the theme supports it)
  • Configure navigation (primary and secondary menus)
  • Adjust theme-specific settings exposed by the active theme (e.g. Source's header style: Landing, Highlight, Magazine, Search, or Off)

Installing a custom theme

  1. Obtain a theme .zip (from the Ghost marketplace or a developer).
  2. Go to Settings → Design → Change theme → Upload theme.
  3. Ghost validates the theme with gscan; warnings and errors are shown before activation.

Warning

Theme uploads have size limits enforced by Ghost: the compressed .zip may be up to 1 GB, any single uncompressed file up to 512 MB, and the total uncompressed size up to 4 GB. Themes exceeding these limits are rejected.

Routes & collections

Advanced site structures (custom collections, taxonomies, and URL patterns) are defined in a routes.yaml file you can download, edit, and re-upload under Settings → Labs. This controls how URLs map to content — for example, putting all posts under /blog/ or building a separate podcast collection.

Note

Editing routes.yaml changes your site's URL structure and can break existing links if done carelessly. Most publications never need to touch it.


9. Comments, Search & Engagement Widgets

Ghost ships several reader-facing widgets that load as lightweight scripts on your public site. You enable and configure them in the admin; themes embed them automatically.

Widget What it does Enabled / configured in
Portal Member signup, sign-in, and account management popup Always available; styled in Settings → Membership
Comments Threaded member comments under posts Settings → Membership → Comments
Search (sodo-search) Instant site search overlay Built into themes; powered by an in-browser index
Signup form Embeddable email-capture form (also usable on external sites) Settings → Membership
Announcement bar A site-wide banner for important messages Settings → Site

Comments

Comments are tied to membership: only signed-in members can comment (you choose whether all members or only paid members may). Members can reply, like, and report comments, and receive notifications.

Tip

Because comments require membership, turning them on is also a gentle nudge for readers to create an account — growing your audience.

Ghost's search (sodo-search) provides an instant overlay that searches posts, pages, authors, and tags as the visitor types, using a client-side index for speed. It works on any theme that includes the search trigger.

Embeddable signup form

The signup form can be embedded on other websites (not just your Ghost theme) to capture email subscribers directly into Ghost. You generate the embed snippet in the admin.


10. Analytics & Stats

Ghost gives you three complementary views of how your publication is doing.

Web analytics

Ghost includes a privacy-conscious web analytics system built on Tinybird. It records page views as sessions and shows you:

  • Top pages and top content
  • Traffic sources and referrers
  • UTM campaign performance (source, medium, campaign, term, content)

Session-level attributes (source, UTM parameters) are captured from the first hit of a session and stay constant for that session, answering "what did people do after arriving from this source?"

Note

Web analytics requires the analytics service (Tinybird) to be configured by your administrator. On Ghost(Pro) it is built in; on self-hosted installs it is optional and set up via configuration. See the Admin Guide for the analytics architecture.

Member & growth stats

The members dashboard shows total members, free vs. paid breakdown, monthly recurring revenue (MRR), and growth over time — plus member attribution showing which posts and sources are converting readers into members.

Email stats

For each sent newsletter you see delivery, open rate, and click activity, with per-link breakdowns powered by the click-tracking redirect described in Email Newsletters.

Milestones

Ghost celebrates growth milestones automatically — member counts (100, 1,000, 10,000, …) and ARR thresholds ($100, $1,000, $10,000, …) trigger in-app notifications.


11. Integrations, APIs & Webhooks

Ghost is designed to plug into the rest of your stack.

Built-in & custom integrations

Under Settings → Integrations you can enable built-in integrations (Zapier, Slack, Unsplash, first-party analytics, and more) or create Custom Integrations. A custom integration gives you:

  • A Content API key (read-only, public data)
  • An Admin API key (full read/write, keep secret)
  • A place to register webhooks

The two APIs

API Auth Use for
Content API Content API key (read-only) Building a custom frontend, pulling posts into another site/app
Admin API Admin API key (JWT) or staff session Creating/updating posts, members, settings — automation & tooling

Base paths on your site:

Content API:  https://your-site/ghost/api/content/
Admin API:    https://your-site/ghost/api/admin/

Webhooks

Webhooks let Ghost notify another service when something happens (a member is created or edited, a post is published, etc.). For example, the member.edited event fires when a member's record changes. You register webhook target URLs on a custom integration.

Tip

Common no-code automations — "add new members to a Google Sheet", "post new articles to Slack" — are built by pairing a Ghost webhook (or the Zapier integration) with the destination service. No custom code required.

Slack notifications

Ghost can post to a Slack channel when you publish, via the built-in Slack integration (configured with an incoming webhook URL).


12. Staff, Roles & Settings

Inviting staff

In Settings → Staff the Owner and Administrators can invite team members by email. Each invitee is assigned a role that scopes what they can do.

Role Capabilities (typical)
Owner Full control; one per site; cannot be deleted
Administrator Full control over content, members, settings, and staff
Editor Manage all posts and invite/manage Authors & Contributors
Author Create and publish their own posts
Contributor Create and edit their own drafts, but not publish

Important

Staff accounts (the people who run the site) are separate from members (your audience). They live in different parts of the admin and have different permission systems.

Staff security

Ghost includes staff device verification (enabled by default via the security.staffDeviceVerification setting): signing in from a new device can require email verification. Brute-force protection rate-limits repeated failed logins and password resets.

Key settings areas

Settings section Controls
General / Site Title, description, timezone, language, social accounts, announcement bar
Design Theme, brand, fonts, navigation
Membership Tiers, Stripe, Portal, comments, access defaults
Email newsletters Newsletter list, sender details, designs
Integrations Built-in & custom integrations, API keys, webhooks
Staff Team members and roles
Advanced / Labs Code injection, routes, redirects, imports/exports, beta features

Code injection

Settings → Code injection lets you add HTML/CSS/JS to your site's header or footer globally (and per-post in post settings) — handy for analytics snippets, custom fonts, or small style tweaks without editing the theme.


13. Importing, Exporting & Backups

Exporting your content

From Settings → Labs → Export you can download a full JSON export of your content (posts, tags, users, settings). This is the canonical portable format and the basis of backups and migrations.

Settings → Labs → "Export your content"  →  downloads a .json file

Importing content

The same Labs area imports a Ghost JSON export, letting you migrate between Ghost installs or restore from a backup. Ghost also offers a members CSV import (members are imported from .csv files) under the Members area.

Note

Member CSV uploads accept the .csv extension and standard CSV content types. The importer records each imported member's attribution as Imported / Member Importer.

What to back up

A complete backup of a self-hosted Ghost site is two things:

  1. The database (your posts, members, settings).
  2. The content/ directory (images, media, files, themes, and data/).

Caution

The content/data/ directory is the home of your SQLite database (on SQLite installs) — the README in that folder warns: do not overwrite this folder or any files inside it. On MySQL installs your data is in MySQL instead, so back up the database server.


14. Developer & Maintenance Commands

The repository exposes a small internal CLI (run as node index.js <command> inside ghost/core, or via the pnpm wrappers). These are development and testing tools — most site owners never need them, but they are documented here for completeness.

generate-data — populate the database

Generates random members, posts, and related data for development and testing.

node index.js generate-data --clear-database --quantities members:1000,posts:100 --seed 123
Option Type Purpose
--base-data-pack string Import a base data pack file instead of random content
--clear-database boolean Clear all entries before importing
--tables string Only import the listed tables, e.g. members:1000,posts,tags
--quantities string Override default quantities per table, e.g. members:1000
--with-default boolean Include default tables in addition to those specified
--print-dependencies boolean Print the data-generator dependency tree and exit
--seed number Use a seed for reproducible data across runs

repl — interactive shell

Launches a REPL with a configured database connection and models available, exposed as knex / k and models / m.

node index.js repl

timetravel — shift database dates

Shifts all date fields in the database forward to the present day (useful for reviving stale test data). By default the offset is based on the most recent member login.

node index.js timetravel --offset 30   # shift everything 30 days forward
node index.js timetravel --force       # skip the confirmation prompt

Caution

timetravel is explicitly described in source as "a destructive operation for testing purposes only. DO NOT run it against a database you care about." It modifies every dated row in your database.

Common repository scripts

Command What it does
pnpm dev Start the full dev environment
pnpm build Build all packages
pnpm test Run the test suites (excludes e2e and admin)
pnpm lint Lint all packages
pnpm fix Reset and reinstall dependencies to fix install issues
pnpm main Update local checkout to latest main
pnpm reset:data Regenerate sample data

15. Troubleshooting

Troubleshooting entries use the format: the symptom → why it happens → how to fix → how to prevent it. Several entries below reference real behaviours and error conditions defined in Ghost's source.

Error: URL in config must be provided with protocol, eg. "http://my-ghost-blog.com"

  • Cause: The url value in your configuration is missing an http:// or https:// prefix. Ghost validates this on startup and refuses to boot without a protocol.
  • Solution: Edit your config (config.production.json or equivalent) so url is a full URL including the scheme, e.g. "url": "https://example.com".
  • Prevention: Always set url to the public address readers will use, with protocol and (if relevant) subdirectory.

Error: Your content path does not exist! Please double check 'paths.contentPath' in your custom config file

  • Cause: Ghost checks that the configured paths.contentPath exists at boot and throws if it does not.
  • Solution: Create the directory (default content/) or correct paths.contentPath in your config. Ensure the Ghost process user can read and write it.
  • Prevention: Keep the content/ directory alongside your install and include it in deploys and backups.

Symptom: Command refuses to run — Command … is not permitted in production

  • Cause: Several internal CLI commands (like repl) are restricted to development/local environments and abort when NODE_ENV is production.
  • Solution: Run development-only commands in a development environment, not on your live server. (generate-data is permitted in all environments but still destructive with --clear-database.)
  • Prevention: Reserve these tools for local/staging machines.

Symptom: Site stuck on a "maintenance" / 503 page

  • Cause: Ghost serves a 503 maintenance page while it is still booting (the URL service hasn't finished) or when maintenance mode is enabled in config. On large sites the first boot can take time to build the URL cache.
  • Solution: Wait for boot to complete; check logs for boot timings. Ensure maintenance.enabled is not set to true in your config.
  • Prevention: Allow adequate boot time after deploys; monitor the boot logs for the "booted" message.

Symptom: Newsletter looks broken in Outlook / some email clients

  • Cause: Email clients (notably Outlook) render HTML very differently from browsers; complex card layouts can mangle.
  • Solution: Send yourself a test email before sending to your list and adjust the post's cards. Prefer simpler layouts for email-heavy content.
  • Prevention: Always test newsletters across at least one desktop and one mobile client before a full send.
  • Cause: Member sign-in relies on transactional email; if email is misconfigured, magic links never arrive. Repeated attempts can also trip brute-force rate limits.
  • Solution: Verify your administrator has configured a working mail transport. Wait out the rate-limit window if it has been triggered (member login allows a limited number of free retries before a cooldown).
  • Prevention: Configure and test email delivery before opening membership.

Symptom: Theme upload rejected

  • Cause: The .zip exceeds Ghost's upload limits (1 GB compressed / 512 MB per file / 4 GB total uncompressed) or fails gscan validation.
  • Solution: Slim the theme (remove node_modules, build artefacts, large unused assets), then re-upload. Address gscan errors shown in the upload dialog.
  • Prevention: Build and zip only the files the theme needs; run gscan locally before uploading.

Symptom: Scheduled post didn't publish at the exact minute

  • Cause: Ghost's scheduler has a small tolerance window and cannot schedule a post in the immediate past; the default scheduling adapter runs in-process.
  • Solution: Confirm the post status is "Scheduled" and the time is in the future. Keep the Ghost process running continuously so the scheduler can fire.
  • Prevention: Schedule a comfortable margin ahead of the desired minute; ensure your host doesn't sleep the process.

Symptom: Images upload but don't appear / wrong sizes

  • Cause: Ghost resizes images and serves responsive srcset variants; if image optimization is disabled or storage is misconfigured, variants may be missing.
  • Solution: Confirm imageOptimization.resize and srcsets are enabled (defaults) and that your storage adapter (local or object storage) is writable.
  • Prevention: Use the default image pipeline unless you have a specific reason to change it.

Symptom: Dev environment won't start / dependency errors

  • Cause: Stale or mismatched dependencies, or submodules not initialised.
  • Solution: Run pnpm fix to prune and reinstall, then pnpm run setup to re-init submodules. Use corepack enable pnpm to ensure the pinned pnpm version.
  • Prevention: Use the pinned Node and pnpm versions; run pnpm main to stay current.

16. Frequently Asked Questions

Q: Is Ghost free? Ghost (this software) is free and open source under the MIT License. You can self-host it at no licensing cost. The Ghost Foundation also runs Ghost(Pro), a paid managed hosting service, but that is optional.

Q: Do I need to know how to code to use Ghost? No. Writing, members, newsletters, design, and settings are all managed visually in the admin. Code is only needed for custom themes or deep integrations.

Q: What database does Ghost need? MySQL 8 in production (using the mysql2 client). SQLite is supported for development. Your administrator chooses this at install time.

Q: Can I run more than one newsletter? Yes. Ghost supports multiple newsletters, each with its own design and subscriber list, and members can opt into each independently.

Q: How do paid subscriptions work? Through Stripe. You connect a Stripe account, define paid Tiers, and Ghost handles checkout and keeps subscriptions in sync via Stripe webhooks. Ghost never stores card details — payment happens on Stripe's secure pages.

Q: Can readers comment? Yes, if you enable Comments. Commenting requires membership, so it doubles as an audience-growth feature. You can allow all members or only paid members to comment.

Q: How do I move my content to another Ghost site? Export a JSON file from Settings → Labs → Export, then import it on the destination site. Members can be moved via CSV. Remember to also move your content/ directory (images and files).

Q: What's the difference between a member and a staff user? Members are your audience (readers, subscribers). Staff users are your team (Owner, Administrators, Editors, Authors, Contributors) who manage the site. They are managed separately and have different permissions.

Q: Does Ghost track my readers? Ghost includes privacy-conscious first-party web analytics and member attribution (which post/source brought a member in). Attribution tracking can be disabled with the members_track_sources setting, and outbound link tagging with outbound_link_tagging.

Q: Can I customise my site's URLs (e.g. put posts under /blog/)? Yes — via the routes.yaml file under Settings → Labs. This is an advanced feature; most sites use the defaults.

Q: How do I add Google Analytics or a custom script? Use Settings → Code injection to add header/footer snippets globally, or the per-post code injection for one-off scripts.

Q: My newsletter went to the wrong people — can I undo it? No. Email sends are immediate and irreversible. Always use the test-email preview and double-check your recipient filter before sending.

Q: How many members can Ghost handle? Ghost is built for scale — the repo even ships a 2-million-member stress-test data generator (pnpm reset:data:xxl). Real-world capacity depends on your hosting; see the Admin Guide.

Q: What is the ghost command vs. node index.js? ghost is Ghost-CLI, the production installer/manager (ghost install, ghost start). node index.js <command> runs the in-repo development CLI (generate-data, repl, timetravel). They are different tools for different jobs.

Q: How do I update Ghost? On a Ghost-CLI install, run ghost update. For the development repo, pnpm main pulls the latest main and reinstalls.

Q: Can I use Ghost as a headless CMS? Yes. Use the Content API to pull posts into a custom frontend (Next.js, Astro, etc.) while still writing in the Ghost admin.


17. Reference Tables

Default URLs & ports

Item Default value
Site URL http://localhost:2368
Admin panel http://localhost:2368/ghost/
Server host 127.0.0.1
Server port 2368
Content API base /ghost/api/content/
Admin API base /ghost/api/admin/

Content directory layout

Folder Holds
content/images/ Uploaded images (when using local storage)
content/media/ Uploaded audio/video
content/files/ Uploaded files (PDFs, docs, etc.)
content/themes/ Installed themes
content/adapters/ Custom storage/scheduling adapters
content/logs/ Production log files
content/data/ Database files (SQLite) — do not overwrite
content/settings/ Route and redirect settings
content/public/ Built public assets

Reader-facing widgets

Widget Default version (CDN)
Portal 2.68
Sodo Search 1.8
Comments UI 1.5
Announcement bar 1.1
Signup form 0.3
Admin toolbar 0.1

Upload limits & allowed types (selected)

Upload type Allowed extensions (selected)
Images .jpg, .jpeg, .gif, .png, .svg, .webp, .ico
Media .mp4, .webm, .ogv, .mp3, .wav, .ogg, .m4a
Files .pdf, .doc(x), .xls(x), .ppt(x), .zip, .csv, .epub, and many more
Members import .csv
Themes .zip (≤ 1 GB compressed)
Redirects .json, .yaml
Routes .yaml

Common commands

Goal Command
Install Ghost (production) ghost install
Start / stop (production) ghost start / ghost stop
Update (production) ghost update
Start dev environment pnpm dev
Generate sample data pnpm reset:data
Empty database pnpm reset:data:empty
Fix dependency issues pnpm fix
Update to latest main pnpm main