Docs / CMS & Website Platforms / Deploy Payload CMS 3.0 on Your VPS

Deploy Payload CMS 3.0 on Your VPS

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 222 views · 2 min read

Payload CMS 3.0 is a modern, code-first headless CMS built with TypeScript and Next.js. Unlike traditional CMS platforms, Payload lives inside your Next.js application, giving you a powerful admin panel, flexible content modeling, and full-stack capabilities in a single deployment. This guide walks you through deploying Payload CMS 3.0 on your Kazepute Breeze.

Why Payload CMS 3.0?

  • Code-first: Define collections and fields in TypeScript — version control your content model
  • Next.js native: Runs inside your Next.js app, not as a separate service
  • Self-hosted: Full control over your data and infrastructure
  • Rich admin UI: Auto-generated admin panel with live preview, drafts, and versioning
  • Database flexibility: Supports MongoDB and PostgreSQL

Prerequisites

# Install Node.js 20+ via nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20

# Install PostgreSQL (recommended for Payload 3.0)
sudo apt update
sudo apt install -y postgresql postgresql-contrib

# Create database
sudo -u postgres createuser payload_user
sudo -u postgres createdb payload_db -O payload_user
sudo -u postgres psql -c "ALTER USER payload_user PASSWORD 'your_secure_password';"

Create a Payload CMS Project

# Create new Payload project
cd /opt
npx create-payload-app@latest my-website

# Select during prompts:
# - Template: website
# - Database: PostgreSQL
# - Package manager: pnpm

cd my-website

# Configure environment
cat > .env  true, // Public read
    create: ({ req: { user } }) => !!user,
    update: ({ req: { user } }) => !!user,
    delete: ({ req: { user } }) => !!user,
  },
  fields: [
    { name: 'title', type: 'text', required: true },
    {
      name: 'slug',
      type: 'text',
      unique: true,
      admin: {
        position: 'sidebar',
      },
      hooks: {
        beforeValidate: [({ data }) => {
          if (data?.title) {
            return data.title.toLowerCase().replace(/\s+/g, '-')
              .replace(/[^a-z0-9-]/g, '');
          }
        }],
      },
    },
    {
      name: 'content',
      type: 'richText',
      required: true,
    },
    {
      name: 'featuredImage',
      type: 'upload',
      relationTo: 'media',
    },
    {
      name: 'category',
      type: 'relationship',
      relationTo: 'categories',
      hasMany: false,
    },
    {
      name: 'publishedAt',
      type: 'date',
      admin: { position: 'sidebar' },
    },
    {
      name: 'status',
      type: 'select',
      options: ['draft', 'published'],
      defaultValue: 'draft',
      admin: { position: 'sidebar' },
    },
  ],
}

Build and Deploy

# Build the application
pnpm build

# Test locally
pnpm start

# Create a systemd service for production
sudo cat > /etc/systemd/system/payload-cms.service         

Was this article helpful?