Headless CMS

    Deploy Strapi 5 on RamNode VPS

    Production-ready headless CMS with PostgreSQL, PM2 process management, Nginx reverse proxy, and SSL encryption.

    Ubuntu 24.04 LTS
    PostgreSQL
    ⏱️ 30-45 minutes

    What is Strapi?

    Strapi is the leading open-source headless CMS built on Node.js and TypeScript. It provides a powerful admin panel for managing content and exposes your data through fully customizable REST and GraphQL APIs.

    • Admin Panel: Intuitive content management UI
    • REST & GraphQL: Dual API out of the box
    • TypeScript: Full type safety support
    • Extensible: Plugin ecosystem and custom fields
    • Role-Based Access: Granular permissions system
    • Media Library: Built-in asset management
    1

    Prerequisites

    • • A RamNode VPS with at least 2 GB RAM and 2 vCPUs (4 GB recommended)
    • • Ubuntu 24.04 LTS installed
    • • A registered domain name with DNS pointed to your VPS IP
    • • SSH access with a non-root sudo user
    • • Basic familiarity with the Linux command line
    ⚠️ Important: Strapi 5 requires Node.js v20 or v22 (LTS versions only). Odd-numbered releases (v21, v23) are not supported. This guide uses Node.js v22 LTS.
    2

    Initial Server Setup

    Connect & Update
    ssh your_user@your_server_ip
    sudo apt update && sudo apt upgrade -y
    Install Build Tools
    sudo apt install -y build-essential curl git
    3

    Install Node.js

    Install Node.js v22 LTS
    curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
    sudo apt install -y nodejs
    Verify Installation
    node -v
    npm -v

    You should see Node.js v22.x and npm v10.x or later. Optionally install Yarn:

    Optional: Install Yarn
    npm install -g yarn
    4

    Install and Configure PostgreSQL

    PostgreSQL is recommended for production — better performance, concurrency, and data integrity than SQLite.

    Install PostgreSQL
    sudo apt install -y postgresql postgresql-contrib
    sudo systemctl start postgresql
    sudo systemctl enable postgresql

    Create Database & User

    Enter PostgreSQL Shell
    sudo -u postgres psql
    SQL Commands
    CREATE USER strapi WITH PASSWORD 'your_secure_password';
    CREATE DATABASE strapidb OWNER strapi;
    GRANT ALL PRIVILEGES ON DATABASE strapidb TO strapi;
    ALTER ROLE strapi CREATEDB;
    \q

    The CREATEDB privilege is needed because Strapi manages schema-level operations during initialization and migrations.

    5

    Create Your Strapi Project

    Create Project Directory
    sudo mkdir -p /var/www
    cd /var/www
    npx create-strapi@latest my-strapi-app

    When prompted, configure:

    • Database client: postgres
    • Database name: strapidb
    • Host: 127.0.0.1 | Port: 5432
    • Username: strapi | Password: your password
    • Enable SSL: No (local PostgreSQL)
    • TypeScript: Recommended
    Set Ownership
    sudo chown -R your_user:your_user /var/www/my-strapi-app
    6

    Configure Environment Variables

    Edit .env File
    cd /var/www/my-strapi-app
    nano .env
    .env Configuration
    HOST=0.0.0.0
    PORT=1337
    APP_KEYS=your_app_key_1,your_app_key_2,your_app_key_3,your_app_key_4
    API_TOKEN_SALT=your_api_token_salt
    ADMIN_JWT_SECRET=your_admin_jwt_secret
    TRANSFER_TOKEN_SALT=your_transfer_token_salt
    JWT_SECRET=your_jwt_secret
    
    DATABASE_CLIENT=postgres
    DATABASE_HOST=127.0.0.1
    DATABASE_PORT=5432
    DATABASE_NAME=strapidb
    DATABASE_USERNAME=strapi
    DATABASE_PASSWORD=your_secure_password
    DATABASE_SSL=false

    Generate each secret with:

    Generate Secrets
    openssl rand -base64 32
    🔒 Security: These secrets are critical for authentication. Never commit them to version control or share publicly.
    7

    Build and Test Strapi

    Build Admin Panel
    NODE_ENV=production npm run build
    Start Temporarily
    NODE_ENV=production npm run start

    Navigate to http://your_server_ip:1337/admin to confirm the admin panel loads. Create your first administrator account. Press Ctrl+C to stop.

    8

    Set Up PM2 Process Manager

    Install PM2
    npm install -g pm2
    ecosystem.config.js
    module.exports = {
      apps: [
        {
          name: 'strapi',
          cwd: '/var/www/my-strapi-app',
          script: 'npm',
          args: 'run start',
          env: {
            NODE_ENV: 'production',
          },
          exp_backoff_restart_delay: 100,
          max_memory_restart: '1G',
          log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
          error_file: '/var/www/my-strapi-app/logs/error.log',
          out_file: '/var/www/my-strapi-app/logs/output.log',
        },
      ],
    };
    Start with PM2
    mkdir -p /var/www/my-strapi-app/logs
    cd /var/www/my-strapi-app
    pm2 start ecosystem.config.js
    Enable Auto-Start on Boot
    pm2 startup systemd
    pm2 save
    Monitor Strapi
    pm2 status
    pm2 logs strapi
    9

    Configure Nginx Reverse Proxy

    Install Nginx
    sudo apt install -y nginx
    /etc/nginx/sites-available/strapi
    upstream strapi {
        server 127.0.0.1:1337;
    }
    
    server {
        listen 80;
        server_name your_domain.com;
    
        client_max_body_size 50M;
    
        location / {
            proxy_pass http://strapi;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $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_cache_bypass $http_upgrade;
        }
    }
    Enable & Test Configuration
    sudo ln -s /etc/nginx/sites-available/strapi /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl restart nginx
    10

    Enable SSL with Let's Encrypt

    Install Certbot
    sudo apt install -y certbot python3-certbot-nginx
    Obtain Certificate
    sudo certbot --nginx -d your_domain.com
    Verify Auto-Renewal
    sudo certbot renew --dry-run

    Your Strapi instance is now accessible at https://your_domain.com/admin with a valid SSL certificate.

    11

    Configure the Firewall

    UFW Configuration
    sudo ufw allow OpenSSH
    sudo ufw allow 'Nginx Full'
    sudo ufw enable
    sudo ufw status

    This allows SSH (port 22) and HTTP/HTTPS (ports 80/443). Strapi's port 1337 is only accessible through the Nginx reverse proxy.

    12

    Configure Production URLs

    config/server.js
    module.exports = ({ env }) => ({
      host: env('HOST', '0.0.0.0'),
      port: env.int('PORT', 1337),
      url: env('PUBLIC_URL', 'https://your_domain.com'),
      app: {
        keys: env.array('APP_KEYS'),
      },
    });

    Add to your .env file:

    Add to .env
    PUBLIC_URL=https://your_domain.com
    Rebuild & Restart
    cd /var/www/my-strapi-app
    NODE_ENV=production npm run build
    pm2 restart strapi
    13

    Maintenance & Management

    Updating Strapi

    Update Strapi
    cd /var/www/my-strapi-app
    npm update
    NODE_ENV=production npm run build
    pm2 restart strapi
    📝 Note: Always review the Strapi release notes before upgrading — major versions may require migration steps.

    Database Backups

    PostgreSQL Backup
    pg_dump -U strapi -h 127.0.0.1 strapidb > /backups/strapidb_$(date +%Y%m%d).sql

    Add this to a cron job for automated daily backups. Store backups off-server for disaster recovery.

    Monitoring Logs

    View Logs
    pm2 logs strapi --lines 100

    Health Check

    Strapi exposes a built-in health check at /_health (HTTP 204). Integrate with monitoring tools like UptimeRobot or your own Grafana stack.

    14

    Recommended VPS Specifications

    Use CaseRAMvCPUsStorage
    Small blog or personal site2 GB230 GB SSD
    Medium business site or API4 GB460 GB SSD
    High-traffic application8 GB+4+100 GB+ SSD
    Strapi's memory usage scales with content types, plugins, and concurrent API requests. For most projects, 2–4 GB provides a comfortable baseline. View Cloud VPS Plans →

    Your Stack

    • Runtime: Node.js v22 LTS
    • Database: PostgreSQL
    • Process Manager: PM2 with automatic restart
    • Web Server: Nginx reverse proxy with SSL
    • SSL: Let's Encrypt with auto-renewal
    • Firewall: UFW (SSH, HTTP, HTTPS only)

    From here, extend your deployment with Strapi plugins, external media storage (Cloudinary, MinIO), or connect frontends like Next.js, Nuxt, or Astro.