Self-hosted service
Cockpit-HQ/Cockpit avatar
Cockpit-HQ/Cockpit

Cockpit, a self-hosted headless CMS with REST and GraphQL APIs

Cockpit Core - Content Platform

755 stars83 forksPHPNOASSERTION

At a glance

What is it?
cockpit-hq/Cockpit is a PHP headless content platform that stores content in SQLite or MongoDB and exposes it through both a REST API and a GraphQL endpoint, with collections, singletons and trees as content models, multi-language support and multi-tenant spaces. It installs from a release ZIP or a Docker image and needs a writable storage directory.
Who is it for?
Adopt Cockpit if you want a content backend your own front end talks to, you can run PHP and a database, and you would rather own the deployment than rent a CMS. Skip it if you need a mature editorial workflow with scheduled publishing and structured content approval, since Cockpit is deliberately a content platform rather than a publishing suite.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Cockpit is and the model it uses

Cockpit is described as a headless CMS that gives you the flexibility to build content-driven applications your way, whether those are websites, mobile apps or IoT applications, with Cockpit providing the content infrastructure.

The content model has three shapes, and they are the thing to understand before anything else. Collections are sets of similar items, such as blog posts or products. Singletons are single documents, such as a site-wide settings object or a homepage. Trees are hierarchical structures, which is what you want for navigation menus or a category hierarchy that nests.

On top of that, the field types are what decide whether the platform fits your data. The feature table says 20+ field types, and the model is defined through the admin UI or through the API, so the schema is data rather than code.

The other structural elements are multi-language support with fallback, which matters for a site with more than one language, and multi-tenancy through spaces, which are separate areas for multiple sites and clients sharing one installation. A multi-tenant SaaS is listed as a use case, and spaces are the mechanism.

The licence field on the repository reports it as a custom licence GitHub cannot classify, and the source is the Core content platform, with the repository named Cockpit and the package published as cockpithq/cockpit. That distinction between a core platform and the surrounding commercial offerings is worth noting before you evaluate the project, because the repository is the open part and the site sells more than that.

The release history shows steady work: 2.13.5 in March 2026, 2.14.0 at the end of March and 2.14.1 in August, with the last push on 2026-10-13 on the develop branch.

Installing it and the requirement list

The quick start offers two routes, and the Docker one is the recommended option.

The traditional route is a release ZIP. You download and extract it, make the storage directory writable, and open the installer in a browser:

bash
# Download and extract
wget https://github.com/cockpit-hq/cockpit/releases/latest/download/cockpit.zip
unzip cockpit.zip && cd cockpit

# Make storage writable  
chmod -R 755 storage/

# Open in browser and complete setup
open http://localhost/cockpit/install

The Docker route runs the published image with a named volume for storage:

bash
# Run Cockpit with persistent storage
docker run -d \
  --name cockpit \
  -p 8080:80 \
  -v cockpit_storage:/var/www/html/storage \
  cockpithq/cockpit:core-latest

The volume mount is the part that matters. Everything Cockpit stores, including the database if you use SQLite, lives under that storage path, so mounting a named volume is what makes the container's contents survive a restart or an image upgrade.

The system requirements are PHP 8.3 or newer with the PDO and GD extensions, a database which is SQLite by default or MongoDB, a web server which is Apache with mod_rewrite or Nginx, and a writable /storage directory. The README also asks that $_SERVER['DOCUMENT_ROOT'] is properly configured, which is a common source of a broken install: the admin interface loads, assets 404, and the cause is the document root rather than anything in Cockpit.

The image tag is core-latest, which tracks the latest core release. The Docker section in the README continues past the quick start with variants including a MongoDB-backed production deployment, and the CLI and API are the next sections.

One thing to note is the age of the requirement floor. PHP 8.3 means the platform is not running on an older distribution's default PHP, which is usually a good sign for a CMS but does narrow the set of hosts it will install on.

The REST and GraphQL APIs side by side

Cockpit exposes the same content through two API styles, and the README shows both.

The REST side lists published posts with a filter, a single post by id, and a create call:

bash
# Get all published blog posts
curl "https://yoursite.com/api/content/items/blog?filter={tags:'cms'}"

# Get single post by ID
curl "https://yoursite.com/api/content/item/blog/60f1b2b3c4d5e6f7a8b9c0d1"

# Create new post
curl -X POST "https://yoursite.com/api/content/item/blog" \
  -H "Cockpit-Token: your-token" \
  -H "Content-Type: application/json" \
  -d '{"title":"New Post","content":"Content here","tags":["cms"]}'

Note the token header. Writes are authenticated with a Cockpit-Token header rather than a bearer token, which is a small detail that trips up code generated from the documentation by someone expecting OAuth conventions.

The GraphQL side queries the same data with pagination and filtering, and mutates it:

graphql
# Query blog posts with pagination
query GetBlogPosts($limit: Int, $skip: Int) {
  blog(limit: $limit, skip: $skip, filter: {tags: "cms"}) {
    _id
    title
    content
    _created
    _modified
  }
}

# Create new blog post  
mutation CreatePost($data: JSON!) {
  saveContentItem(model: "blog", data: $data) {
    _id
    title
  }
}

The GraphQL schema is generated from your content models, which is why the query names a collection, blog, as a top level field rather than going through a generic contentItem type. The mutations take a model name and a JSON payload, so the shape of the data is opaque to the schema. The metadata fields whose names begin with a low line, _id, _created and _modified, are always present.

The consequence for a front end is that you can query exactly the fields you defined and nothing else, which is the appeal of a headless CMS. The cost is that every content model change alters the schema, and a client with a hand-written query needs updating when a field is renamed.

For a quick start in JavaScript, the README shows fetching a collection directly:

javascript
// Fetch your content anywhere
fetch('/api/content/items/blog')
  .then(res => res.json())
  .then(posts => {
    // Use in React, Vue, mobile apps, etc.
    console.log('My content:', posts);
  });

The feature set and where Cockpit is deliberately thin

The feature table is a good map of the product, and it is worth reading as a set of commitments rather than a list.

Content modelling is collections, singletons and trees with 20+ field types. Asset management covers image processing, video thumbnails and CDN integration, which is more than a bare file uploader. User management includes roles, permissions, two-factor authentication and API tokens. Multi-language is built in with fallback support, and the developer tools are a GraphQL playground, REST documentation and CLI commands. Extensibility covers custom fields, addons, hooks and events, which is the mechanism for anything the core does not do. Multi-tenancy is spaces for multiple sites and clients.

What is not on that list is as informative. There is no mention of scheduled publishing, revision history, content approval workflows, a built-in frontend, or a marketing-oriented editor. That is the shape of a headless CMS: the editorial surface is an admin UI for defining models and entering content, and the presentation is somebody else's problem.

For a team whose content is structured and published by an API to a React app, that is exactly right. For a team running a magazine or a documentation site where writers need a distraction-free editor, scheduled publishing, and a way to see what the page will look like, it is a significant gap that you fill with your own frontend or with a different platform.

The Docker and multi-space support close the loop for the SaaS case, and the use case list in the README confirms the intended market: headless websites on a JAMstack, mobile apps with native or hybrid frameworks, e-commerce product catalogues, corporate sites, IoT dashboards, and multi-tenant platforms.

The documentation is at getcockpit.com/documentation, the community runs on a Discourse forum at discourse.getcockpit.com, and the project is not archived. The one thing to resolve before investing is the licence, since the repository does not report a standard identifier and the site sells more than the open core.

Editorial conclusion

Adopt Cockpit if you want a content backend your own front end talks to, you can run PHP and a database, and you would rather own the deployment than rent a CMS. Skip it if you need a mature editorial workflow with scheduled publishing and structured content approval, since Cockpit is deliberately a content platform rather than a publishing suite. Verify first by running the Docker image on a local port, creating one collection and one content item through the API, and confirming the item is reachable from both the REST and GraphQL endpoints before you model the rest of your content.

Frequently asked questions

What content models does Cockpit support?

Three shapes: Collections for sets of similar items, Singletons for single documents such as site settings, and Trees for hierarchical structures such as navigation menus. Each supports 20 or more field types, and the models are defined through the admin UI or the API.

How do I install Cockpit?

With Docker, which the README recommends, running the cockpithq/cockpit:core-latest image with a named volume mounted at /var/www/html/storage so the data survives restarts. The traditional route is to download the release ZIP, make the storage directory writable and open the installer at /cockpit/install.

What are the system requirements for Cockpit?

PHP 8.3 or newer with the PDO and GD extensions, SQLite by default or MongoDB, Apache with mod_rewrite or Nginx, and a writable /storage directory. The README also asks that $_SERVER['DOCUMENT_ROOT'] is configured correctly, which is a common cause of a broken install.

How do I authenticate a write request to the Cockpit REST API?

With a token sent in a Cockpit-Token header, alongside a Content-Type of application/json, rather than with a bearer token. The same data is also available over GraphQL through a playground in the admin interface.

Does Cockpit support multi-tenancy and multiple languages?

Yes. Multi-tenancy is provided through spaces, separate areas for multiple sites and clients sharing one installation, and multi-language support is built in with fallback behaviour for content that has not been translated.

Official sources

  1. Cockpit-HQ/Cockpit on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cockpit-hq-cockpit.svg)](https://hysenlabs.com/projects/cockpit-hq-cockpit)

Was this useful?