|Docs

Self-host Payload CMS with Postgres

deploymentfrontendpayloadcms

Payload CMS is a TypeScript-native headless CMS that runs inside a Next.js application. Starting with version 3.0, Payload embeds directly in your Next.js app, sharing the same server, routes, and build process.

This guide covers deploying Payload CMS 3.x on Railway with a Postgres database and media storage.

What you will set up

  • A Payload CMS instance running inside Next.js
  • A Postgres database for content storage
  • Media uploads via a Railway Storage Bucket
  • A public domain for the admin panel and API

Create a Payload project

Select the Postgres database adapter and your preferred template during setup. Push the project to a GitHub repository.

Deploy to Railway

1. Create the project and database

  1. Create a new project on Railway.
  2. Add a PostgreSQL database: click + New, then Database, then PostgreSQL.
  3. Deploy the app: click + New, then GitHub Repo, and select your repository.

2. Configure environment variables

Add the following variables to the Payload service:

Generate the secret with:

Set NEXT_PUBLIC_SERVER_URL after generating a domain (next step). This variable tells Payload its public URL for generating links in the admin panel.

3. Configure standalone output

Set output: "standalone" in next.config.js:

4. Generate a domain

Navigate to Networking in the service settings and generate a domain. Update the NEXT_PUBLIC_SERVER_URL variable to match the generated domain.

Open https://your-domain.railway.app/admin to create your first admin user.

Media storage

By default, Payload stores media on the local filesystem, which is ephemeral on Railway. Configure an S3-compatible storage provider for persistent media.

  1. Create a Storage Bucket in your Railway project.
  2. Install the storage adapter:
  1. Add the adapter to your Payload config:
  1. Add the bucket credentials to your service variables.

Connecting a frontend

Payload exposes a REST API at /api and a GraphQL API at /api/graphql. Since Payload runs inside Next.js, you can also use Server Components to query content directly:

For a separate frontend (e.g., a standalone React app), call the REST API:

Build memory

Payload with Next.js can be memory-intensive during builds, especially with many collections and plugins. If the build fails with an out-of-memory error, increase the Node.js heap size by adding this variable:

Next steps