Strapi is a popular open-source headless CMS — providing a content management backend with a REST/GraphQL API, without dictating any specific frontend technology. This guide covers self-hosted installation.
What Makes Strapi Different from Traditional CMS Platforms
Unlike Drupal or Joomla (which render frontend pages themselves), Strapi is API-first — content editors manage content through Strapi's admin panel, while your actual website/app frontend consumes that content via API, similar in architecture to the pattern in How to Set Up a Headless E-commerce Architecture.
Step 1 — Install Node.js
See How to Set Up Node.js on AlmaLinux/Rocky Linux or the equivalent Ubuntu/Debian setup guide — Strapi requires a current Node.js version.
Step 2 — Create a New Strapi Project
npx create-strapi-app@latest my-project --quickstart
The quickstart option uses SQLite by default, appropriate for testing; for production, configure PostgreSQL or MySQL instead.
Step 3 — Configure for Production Database
DATABASE_CLIENT=postgres
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=strapi
DATABASE_USERNAME=strapi_user
DATABASE_PASSWORD=CHANGE_ME
See How to Install PostgreSQL and Configure It for Production Use for the underlying database setup.
Step 4 — Build and Start in Production Mode
npm run build
npm run start
Step 5 — Run as a Persistent Service
[Unit]
Description=Strapi CMS
After=network.target
[Service]
WorkingDirectory=/opt/strapi/my-project
ExecStart=/usr/bin/npm run start
Restart=always
User=strapi
[Install]
WantedBy=multi-user.target
Step 6 — Set Up Nginx Reverse Proxy with HTTPS
See How to Set Up Nginx as a Reverse Proxy for Node.js Apps — standard reverse proxy pattern with Let's Encrypt, since Strapi runs as a Node.js application on a specific port.
Creating Content Types
Through Strapi's admin panel, define content types (Articles, Products, and similar) with their fields — this generates the corresponding API endpoints automatically, no manual API coding needed for basic CRUD operations.
Consuming the API from a Frontend
const articles = await fetch('https://cms.yourdomain.com/api/articles').then(r => r.json());
See How to Deploy a Next.js Application on a VPS or your chosen frontend framework — build your actual customer-facing site as a separate application, consuming content from Strapi's API.
Setting Up API Permissions
Strapi's admin panel lets you configure exactly what content is publicly accessible via API versus requiring authentication — review and restrict permissions deliberately, since default settings may be more permissive than appropriate for production.
Backing Up Strapi Content
See How to Set Up Automated VPS Backups — back up both the database (containing your actual content) and any uploaded media files, following the same backup discipline as other production applications.
Common Errors
Admin panel accessible but API returns 403 for public content — verify you've explicitly enabled public access for the specific content type/action in Strapi's Roles & Permissions settings; content types don't have public API access by default.
Continue Reading
- How to Install PostgreSQL on Ubuntu & Debian
- How to Deploy a Next.js Application on a VPS
- How to Set Up Nginx as a Reverse Proxy for Node.js Apps
Browse more articles in CMS Platforms Beyond WordPress.