Special Offers: Up to 75% OFF on Hostinger & High-RAM Contabo Cloud VPS available this month.Compare Plans

How to Deploy Strapi Headless CMS on Ubuntu 24.04 VPS with PostgreSQL & PM2

Marcus Sterling
Marcus SterlingDevOps & Cloud Engineer
October 30, 2026
•
15 min read
•
4.9 / 5.0
Transparency Notice: This article contains affiliate links to hosting providers like Hostinger and Contabo. If you purchase through our links, we may earn a commission at zero extra cost to you. We only recommend products we personally benchmark and test. Read full disclosure.
How to Deploy Strapi Headless CMS on Ubuntu 24.04 VPS with PostgreSQL & PM2
Best Hardware Value for TechsNo Contract Surcharges + High RAM

Contabo High-Performance Cloud VPS

Massive 4 vCPU cores, 8GB RAM, and 32TB monthly traffic. Ideal for Linux developers.

German Engineering & Data Centers
8 Strategic Global Locations
Fast NVMe Storage Array
Full Root & SSH Console Access
Starts From
$5.50 / mo
Special Affiliate Pricing
Claim Discount Now
Official Partner Link • Verified Safe

The Shift Toward Headless Architecture

Modern frontend frameworks like Next.js, Remix, and Astro require high-performance, decoupled content management systems. While commercial headless options like Contentful or Sanity charge hundreds of dollars once API request thresholds are exceeded, Strapi v5 gives developers full control over content schemas, media storage, and relational database queries with zero subscription fees.

Step 1: Installing System Prerequisites

Strapi requires Node.js 18 or 20+, a relational database, and build tools:

# Update base system
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl build-essential git

# Install Node.js 20 LTS via NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# Install PM2 globally
sudo npm install -g pm2

Step 2: Installing and Configuring PostgreSQL 16

sudo apt install -y postgresql postgresql-contrib

# Create isolated database and user for Strapi
sudo -u postgres psql
CREATE DATABASE strapi_prod;
CREATE USER strapi_user WITH ENCRYPTED PASSWORD 'A_SUPER_SECURE_PASSWORD';
GRANT ALL PRIVILEGES ON DATABASE strapi_prod TO strapi_user;
\c strapi_prod
GRANT ALL ON SCHEMA public TO strapi_user;
\q

Step 3: Creating and Configuring Strapi Project

Create your production Strapi application:

cd /var/www
sudo mkdir strapi && sudo chown $USER:$USER strapi
cd strapi

npx create-strapi-app@latest my-project --quickstart=false

When prompted for database configuration:

  • Database client: postgres
  • Host: 127.0.0.1 | Port: 5432
  • Database name: strapi_prod
  • Username: strapi_user
  • Password: Your database password

Step 4: Building Strapi for Production

Compile the React admin dashboard:

cd /var/www/strapi/my-project
NODE_ENV=production npm run build

Step 5: Managing Strapi with PM2

Create a PM2 configuration file ecosystem.config.js:

nano ecosystem.config.js
module.exports = {
  apps: [
    {
      name: "strapi-production",
      cwd: "/var/www/strapi/my-project",
      script: "npm",
      args: "run start",
      env: {
        NODE_ENV: "production",
        PORT: 1337
      }
    }
  ]
};

Start the daemon:

pm2 start ecosystem.config.js
pm2 save
pm2 startup systemd

Step 6: Setting Up Nginx Reverse Proxy with SSL

Create an Nginx configuration file in /etc/nginx/sites-available/cms.yourdomain.com:

server {
    listen 80;
    server_name cms.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:1337;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

Activate the site and secure with Let's Encrypt:

sudo ln -s /etc/nginx/sites-available/cms.yourdomain.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d cms.yourdomain.com

Frequently Asked Questions (FAQ)

How do I handle file uploads in Strapi on a VPS?

You can either store media assets locally on your server filesystem or use the official Strapi Cloudinary or AWS S3 upload provider to offload images to external buckets.

Editorial Verdict: Pros & Cons

What We Love (Pros)

  • 100% self-hosted REST and GraphQL API engine with zero SaaS user limits
  • Contabo VPS provides the high RAM necessary for Node.js build processes and PostgreSQL caching
  • Automatic restart and process monitoring via PM2

Drawbacks (Cons)

  • Building Strapi admin panel requires at least 2GB of free RAM during compilation
Best Hardware Value for TechsNo Contract Surcharges + High RAM

Deploy Your Contabo Cloud Server

Includes 4 vCPU Cores, 8GB RAM, 50GB NVMe SSD, and 32TB Outbound Traffic.

German Engineering & Data Centers
8 Strategic Global Locations
Fast NVMe Storage Array
Full Root & SSH Console Access
Starts From
$5.50 / mo
Special Affiliate Pricing
Claim Discount Now
Official Partner Link • Verified Safe
#Strapi#Headless CMS#Node.js#PostgreSQL#Contabo VPS
Marcus Sterling

Written by Marcus Sterling

DevOps & Cloud Engineer

Alex and the ServerCraft engineering lab run routine benchmarks on over 25 web hosting providers, maintaining strict objectivity and reproducibility.

Recommended Next Reads