Strapi CMS on Debian 12 (PostgreSQL, PM2, Nginx, SSL)

Strapi is a leading open-source headless CMS built on Node.js, offering robust content management with customizable APIs (REST & GraphQL). It allows developers to quickly create structured content APIs for websites, mobile apps, and backend services.

When deployed on Debian 12 Bookworm, Strapi benefits from the OS’s stability, security updates until 2028, and strong compatibility with production-grade software stacks. Integrating PostgreSQL, PM2, Nginx, and SSL completes a hardened and scalable architecture.


Technology Stack Overview

ComponentRole
Debian 12Stable Linux OS with long-term support
Strapi CMSNode.js-based CMS backend exposing REST/GraphQL APIs
PostgreSQLRelational database for content and user data
PM2Node.js process manager for production lifecycle control
NginxReverse proxy handling HTTPS, compression, and routing
SSL/TLSSecure communication via Let’s Encrypt or custom certs

PostgreSQL for Strapi on Debian 12

PostgreSQL is preferred over SQLite or MySQL for its:

  • JSONB support for dynamic content structures
  • High concurrency performance
  • Advanced indexing and full-text search
  • Rich role/permission management
  • Built-in SSL and encryption options

Debian 12 includes PostgreSQL 15 via its main repository, making it easy to configure and maintain using systemd and pgAdmin or CLI tools.


PM2 – Managing Strapi as a Persistent Service

PM2 is a production-grade process manager designed for Node.js applications. With PM2, you gain:

  • Daemonized Strapi instances that auto-restart on crashes
  • Startup script generation for system reboots
  • Real-time monitoring and logging
  • Support for cluster mode to utilize multiple CPU cores
  • Deployment configurations using ecosystem files

PM2 integrates well with systemd, allowing clean service integration within Debian’s native init system.


Nginx + SSL – Frontline Proxy and Encryption Layer

Nginx serves as a reverse proxy in front of Strapi (typically running on port 1337), providing:

  • Public-facing HTTPS endpoint using Let’s Encrypt with Certbot or custom certificates
  • HTTP/2 and gzip compression for optimized performance
  • Path-based routing for API and static asset delivery
  • Security headers and request filtering
  • SSL termination and caching for load reduction

With Nginx on Debian 12, configuration is simple and resilient, thanks to native support for OpenSSL 3.0 and systemd-managed services.


Security Best Practices on Debian 12

Running Strapi securely involves a multi-layered approach:

  • Enforce HTTPS-only access through Nginx
  • Use firewall rules (e.g., ufw or nftables) to expose only ports 80 and 443
  • Restrict direct access to port 1337 (Strapi backend)
  • Use .env variables to store secrets and database credentials securely
  • Enable role-based access control (RBAC) within the Strapi admin UI
  • Regularly update Strapi and its plugins
  • Use Fail2Ban to protect the Nginx login endpoints

Debian 12’s AppArmor support can also be used to sandbox Nginx and Node.js processes for added isolation.


Common Use Cases for This Stack

  • Multi-channel content APIs for JAMstack apps (Next.js, Nuxt, Astro)
  • CMS for mobile apps (Flutter, React Native) with GraphQL integration
  • Corporate intranets and knowledge bases
  • Digital product catalogs with custom roles and workflows
  • Editorial platforms with multiple content types and authors
  • eCommerce headless backends (with Snipcart, Stripe, or custom carts)

Strapi’s plugin system allows adding internationalization (i18n), media management, GraphQL, SSO, and workflows with ease.


Comparison: Strapi vs. Other Headless CMS Options

FeatureStrapiDirectusKeystoneJSPayload CMSContentful (SaaS)
Self-hosted✅✅✅✅❌
PostgreSQL Support✅✅✅✅❌
Admin PanelBuilt-inBuilt-inBuilt-inBuilt-inWeb-based
GraphQL SupportOptionalBuilt-inBuilt-inBuilt-in✅
Open SourceMIT LicenseGPLMITMIT❌ Proprietary
Plugin EcosystemMatureGrowingLimitedLimitedProprietary

Strapi offers the best balance between developer control, feature richness, and extensibility when self-hosting on Linux.


Running Strapi CMS on Debian 12 with PostgreSQL, PM2, Nginx, and SSL offers a secure, scalable, and production-ready platform for building modern content APIs.

Key advantages include:

  • Full control over content structure and APIs
  • PostgreSQL-backed scalability and performance
  • Process resilience with PM2
  • Secure, performant frontend via Nginx and HTTPS
  • Long-term support and OS-level stability from Debian

This stack is well-suited for both small teams launching MVPs and enterprises managing high-traffic digital experiences.


Step 1: Create a Debian 12 VPS on Shape.Host

Go to https://shape.host and log in.

Click “Create”, then choose “Instance”.

Shape.host Resources dashboard with Create > Instance highlighted.

Choose a server location closest to your users.

Shape.host instance form with the data center location selector highlighted.

Select Debian 12 (64-bit) as the operating system.

Choose a plan with at least 2 CPUs, 4 GB RAM, and 20 GB SSD.

Shape.host instance form with the operating system image selector highlighted.

Click “Create Instance”.

Shape.host instance form with the Create Instance button highlighted.

Copy the IP address from the “Resources” section.

Shape.host Resources dashboard with the server IP address highlighted.

Step 2: Connect to Your Server

ssh root@your-server-ip

Step 3: Install System Packages

apt update && apt upgrade -y
apt install curl wget nano gnupg2 ca-certificates lsb-release unzip software-properties-common
Terminal showing APT package management commands and output.
Terminal showing APT package management commands and output.

Step 4: Install and Configure PostgreSQL

apt install postgresql postgresql-contrib
Terminal showing APT package management commands and output.

Then run:

su - postgres -c psql

Inside the PostgreSQL prompt:

CREATE DATABASE strapidb;
CREATE USER strapiuser WITH ENCRYPTED PASSWORD 'YourStrongPassword';
ALTER DATABASE strapidb OWNER TO strapiuser;
\q
Terminal showing SQL database and user configuration commands.

Step 5: Install Node.js 20 and NPM

curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install nodejs
node -v
npm -v
npm install -g npm@11.5.2
Terminal showing APT package management commands and output.
Terminal showing APT package management commands and output.
Terminal showing Node.js or npm version output.
Terminal showing npm package installation messages.

Step 6: Create and Build a Strapi Project

npm create strapi-app@latest my-project
cd my-project
NODE_ENV=production npm run build
Terminal showing Strapi project creation prompts and progress.
Terminal showing file and directory setup commands.

Step 7: Install PM2 and PostgreSQL Client for Node.js

npm install -g pm2 pg
Terminal showing PM2 application process management output.

Step 8: Configure PM2 to Run Strapi

Create the ecosystem file:

nano ecosystem.config.js

Paste the following:

module.exports = {
  apps: [
    {
      name: 'strapi',
      cwd: '/root/my-project',
      script: 'npm',
      args: 'start',
      env: {
        NODE_ENV: 'production',
        HOST: '127.0.0.1',
        PORT: '1337',
        DATABASE_CLIENT: 'postgres',
        DATABASE_HOST: '127.0.0.1',
        DATABASE_PORT: '5432',
        DATABASE_NAME: 'strapidb',
        DATABASE_USERNAME: 'strapiuser',
        DATABASE_PASSWORD: 'YourStrongPassword'
      }
    }
  ]
};
Terminal showing web server configuration text.

Start and enable PM2:

pm2 start ecosystem.config.js
pm2 startup
pm2 save
Terminal showing PM2 application process management output.
Terminal showing systemd service management commands or output.
Terminal showing PM2 application process management output.

Step 9: Install and Configure Nginx

apt install nginx
Terminal showing APT package management commands and output.

Create a config file:

nano /etc/nginx/sites-available/strapi

Paste the following:

server {
    listen 80;
    server_name your_domain.com;

    location / {
        proxy_pass http://127.0.0.1:1337;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_cache_bypass $http_upgrade;
    }
}
Terminal showing web server configuration text.

Enable the site and reload Nginx:

ln -s /etc/nginx/sites-available/strapi /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Terminal showing systemd service management commands or output.

Step 10: Secure Your Domain with Let’s Encrypt SSL

apt install certbot python3-certbot-nginx
certbot --nginx -d debian-tutorials.shape.host -m contact@shape.host --agree-tos --no-eff-email
Terminal showing APT package management commands and output.
Terminal showing Certbot certificate commands and messages.

Your Strapi CMS is now live at:

https://debian-tutorials.shape.host
Strapi initial administrator registration form.
Strapi administration home page.

Use Shape.Host for fast and scalable Linux SSD VPS solutions for all your web projects