Skip to main content
AC
Content & Publishing3.9 KBMIT licensed

ghost-publisher

Original, written for TechTide client work

Deploy and publish on Ghost, the open-source CMS with built-in newsletter and memberships. Use when moving a publication off a hosted platform, publishing via the Ghost Admin API, or deciding whether Ghost is the right migration target. Not for a lightweight self-hosted list without a CMS: use listmonk-publisher. Not for hosted newsletter operations: use beehiiv.

  • ghost
  • publisher

SKILL.md

Ghost Publisher

Ghost is the migration target when a publication outgrows hosted platforms: full SEO control, 0% platform fee (payment processing only), your domain, your audience data. Do not migrate before the numbers justify the ops burden.

Migrate or stay

Recommend Ghost when at least one holds:

  • Paid subscriber revenue makes a ~10% platform fee materially painful (typically past ~50 paid subscribers).
  • You need SEO control a hosted platform will not give you: canonicals, meta, structured data, sitemap.
  • You need to consolidate content on your own domain, or you need audience data portability with no platform lock-in.

None hold: stay on the hosted platform, revisit quarterly. Setup cost is real and recurring.

Deploy

  1. Run Ghost as a long-lived HTTP service on port 2368 behind your reverse proxy, on whatever host you operate ($WORKDIR, VPS, or container platform).
  2. Point your custom domain at it, force HTTPS.
  3. Configure SMTP for transactional mail and newsletter delivery.
  4. For paid memberships, connect Stripe in Ghost admin. You pay processing (~2.9%), no platform cut.

Publish via Admin API

  1. Create an Admin API integration in Ghost admin, store the key as $GHOST_ADMIN_API_KEY, never in the repo.
  2. Post content:
curl -X POST "https://<YOUR_DOMAIN>/ghost/api/admin/posts/?source=html" \
  -H "Authorization: Ghost $GHOST_JWT" \
  -H "Content-Type: application/json" \
  -d '{"posts":[{"title":"<TITLE>","html":"<BODY_HTML>","status":"draft"}]}'

Note: the Admin API takes a short-lived JWT signed with the API key, not the raw key. Generate it per request.

  1. Always create as draft, review in Ghost admin, then publish. Newsletter send happens at publish time when the post is set to email, so a bad autopublish is an unrecallable send.

Good vs bad

Bad: 30 free subscribers, zero paid, and you spend a week self-hosting Ghost for "control", then another week a month patching it. The publication gains nothing.

Good: 80 paid subscribers on a hosted platform taking 10%. You deploy Ghost, migrate content with redirects mapped, connect Stripe, and the fee saving pays the hosting bill several times over.

Verification

After deploy or publish, run curl -s -o /dev/null -w "%{http_code}" https://<YOUR_DOMAIN>/ghost/api/admin/site/ with a valid JWT. Expect 200 and, for a publish, the post visible at its public URL with correct canonical and meta tags in view-source. If not, check the reverse proxy and the JWT generation before touching Ghost config.

Completion checklist

  • [ ] Migration decision backed by the three criteria, not preference
  • [ ] HTTPS on the custom domain, admin reachable
  • [ ] SMTP configured and a test mail delivered
  • [ ] Stripe connected if paid tiers exist
  • [ ] API posts created as drafts, published only after review
  • [ ] Redirects mapped for every migrated URL

Any box unchecked: not done. Fix or say so.

Footguns

  • Publishing straight to `published` via API. If the post is set to email members, the send fires immediately and cannot be recalled. Fix: status: "draft" always, publish from admin.
  • Migrating without redirects. Old platform URLs 404 and rankings evaporate. Fix: map every old URL to its new path in Ghost's redirects file before switching DNS.
  • Raw API key in Authorization. The Admin API rejects it or, worse, you leak the key in logs. Fix: sign a short-lived JWT from the key per request.

More in Content & Publishing

All skills