A headless CMS manages content (articles, products, pages, media), and delivers it through an API, leaving the presentation to your frontend: a static site, a Next.js app, a mobile app, or all of them. Several excellent options are open source and run on your own VPS. Here’s how they compare.

Background: Jamstack explained.

At a glance

CMS Stack APIs Best for
Strapi Node.js; PostgreSQL/MySQL/SQLite REST + GraphQL Custom content models, developer-friendly admin. See deploy Strapi
Directus Node.js; wraps any SQL database REST + GraphQL Admin UI on top of existing databases; data apps. See deploy Directus
Payload Node.js/Next.js; MongoDB or Postgres REST + GraphQL + local API Code-first config in TypeScript; app + CMS in one
Ghost Node.js; MySQL Content API Blogs, newsletters, memberships. See Ghost
WordPress (headless) PHP; MySQL REST + WPGraphQL Familiar editing, huge plugin ecosystem. See headless WordPress
Decap / TinaCMS (Git-based) Content in Git (Markdown) Git Small sites, docs, developer-run blogs

Key differences

Content modelling. Strapi and Payload define content types in the admin or in code. Directus introspects your SQL database, so you can put an admin panel on an existing schema. Ghost has a fixed model (posts, pages, tags, members), which is simple but less flexible.

Editing experience. Ghost and WordPress offer polished writing experiences. Strapi, Directus and Payload are better for structured data (products, events, translations) than for long-form writing, though all have rich text editors.

API style. All offer REST, and most GraphQL. Payload’s local API (direct function calls inside a Next.js app) avoids HTTP overhead.

Licensing. Strapi (MIT community edition), Payload (MIT), Ghost (MIT) and WordPress (GPL) are open source. Directus uses the BSL, which is free for organisations under a revenue threshold. Check current terms for commercial use.

Hosting requirements

CMS Typical small setup
Strapi / Payload / Directus Node.js + PostgreSQL, 1–2 vCPU, 2 GB RAM
Ghost Node.js + MySQL, 1–2 GB RAM
WordPress PHP-FPM + MySQL, 1–2 GB RAM
Git-based No server needed (only for the site build)

All run well with Docker Compose on a VPS, with Nginx in front for HTTPS, and media in local storage or S3-compatible object storage. See Docker Compose in production and MinIO.

Connecting the frontend

  1. The CMS fires a webhook on publish.
  2. CI rebuilds the static site (or the framework revalidates the changed pages).
  3. The new build is deployed.

Lock down the admin UI (strong passwords, 2FA, optional IP restriction), and give the frontend a read-only API token. See API security best practices.

Which to choose

Situation Suggestion
Blog or publication with newsletters Ghost
Custom structured content, developer team Strapi or Payload
Admin UI over an existing SQL database Directus
Editors already love WordPress Headless WordPress
Small developer-run site Git-based (Decap, or plain Markdown)

Backups and updates

Back up the database and uploaded media, and update CMSs regularly (admin panels are attack targets). Test major upgrades on staging. See updating self-hosted apps and database backup automation.

Quick reference

CMS One-line summary
Strapi Flexible Node.js CMS with content-type builder
Directus Admin + API on any SQL database
Payload TypeScript, code-first, Next.js-native
Ghost Publishing + memberships
WordPress Familiar, huge ecosystem

Related: static site generators compared and deploy Next.js on a VPS.

  • CMS
  • Web Development
  • Self-Hosting