Self-host Payload CMS with Postgres
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
- Create a new project on Railway.
- Add a PostgreSQL database: click + New, then Database, then PostgreSQL.
- 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.
- Create a Storage Bucket in your Railway project.
- Install the storage adapter:
- Add the adapter to your Payload config:
- 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
- Storage Buckets - Configure media storage.
- Next.js deployment guide - Additional Next.js deployment options.
- Deploy a Full-Stack Next.js App - Add background workers and more.
- Manage environment variables - Handle public vs server-only variables.