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