Railway

Deploy Payload

Headless CMS for managing content behind a REST and GraphQL API

Deploy Payload

/var/lib/postgresql/data

Just deployed

Just deployed

payload-media

Bucket

Just deployed

Payload logo

Deploy and Host Payload on Railway

Payload is an open-source, TypeScript-native headless CMS that runs inside a Next.js application rather than beside one. You define collections, fields and access control in code; Payload generates the admin panel, a REST API, a GraphQL API and fully typed queries from that definition. Because the schema is code it lives in your repository, reviews like code and deploys like code. Editors still get drafts, versions and scheduled publishing.

This template deploys Payload as three cooperating Railway services. The payload service serves the admin panel, the REST and GraphQL APIs and a public page; a managed PostgreSQL database stores content, versions and users; and an object storage bucket holds every uploaded file. A second payload-jobs service runs the job queue on its own schedule, so background work never competes with API response times. Self-host Payload on Railway and the first deploy arrives with migrations applied, an admin created and uploads landing in durable storage.

Diagram of the Payload, jobs worker and Postgres services on Railway

Getting Started with Payload on Railway

Set PAYLOAD_ADMIN_EMAIL and PAYLOAD_ADMIN_PASSWORD before you click Deploy — those two create your administrator account on first boot, and nothing else is required. When the deploy finishes, open the generated URL: you land on a public page listing published posts. Go to /admin and sign in. The first-run account screen is already closed, so nobody who finds the URL first can claim the instance.

The dashboard shows three collections: Users, Media and Posts. Open Media and upload an image — it goes straight to the bucket and Payload generates resized variants. Then open Posts, create a document, attach that image as the hero, write in the rich text editor and press Publish. Confirm the deployment works end to end by visiting /api/posts logged out: only published documents appear, which proves the database, the access rules and the API layer are wired correctly. To exercise the worker, open a draft and use Schedule Publish from the menu beside the publish button.

Payload post editor showing rich text and a hero image Payload media library listing an uploaded image with alt text Version history where the scheduled version is currently published Public page listing two published posts from the API

About Hosting Payload

Payload solves the problem every custom application hits: the content model keeps changing and the admin interface built for it falls behind. Describe your data once, and Payload derives the interface, the APIs and the types from it. Self-host it when the content belongs to you, or when your frontend already runs on Next.js and a second hosted service is redundant.

Key capabilities:

  • Collections defined in TypeScript, with generated types you import in your frontend
  • Drafts, version history, autosave, scheduled publish and unpublish
  • REST and GraphQL APIs from the same schema, plus a Local API that skips HTTP
  • Field-level access control: a role can read a document but not one field on it
  • Lexical rich text with custom blocks, and uploads with automatic image resizing

The split is deliberate. The payload service is stateless — nothing on local disk — which lets you raise its replica count as traffic grows. PostgreSQL holds every document, draft and version. Object storage holds uploads, and Payload streams files back through its own /api/media/file/ route so access control still applies. The payload-jobs service runs payload jobs:run on a cron, which is what Payload's documentation recommends for a dedicated server.

Why Deploy Payload on Railway

Railway removes the setup work that self-hosting a Next.js CMS usually involves.

  • Managed PostgreSQL, connected by reference, with backups and no tuning
  • Object storage for uploads, so images survive every redeploy
  • Migrations and admin seeding run automatically on each deploy
  • Private networking between app, worker and database
  • A public HTTPS domain with certificates handled for you
  • Push to the repository and both services rebuild

Common Use Cases

  • Marketing sites and blogs on Next.js — CMS and frontend share one repository, one deploy, one set of types.
  • A backend for mobile and multi-channel apps — model content once, consume it over REST or GraphQL.
  • Internal admin tooling — field-level access control replaces a hand-built dashboard.
  • Catalogues and documentation — versioned, scheduled content with media in object storage.

Dependencies for Payload

  • Payload 3.88 on Next.js 16 — built from gridalpha/payload-railway on Node 24
  • PostgreSQL 18 — managed database holding content, drafts, versions and users
  • Railway object storage — an S3-compatible bucket for uploaded files
  • Jobs worker — the same image with PAYLOAD_ROLE=jobs, draining the queue on a schedule

Environment Variables Reference

VariablePurpose
PAYLOAD_SECRETSigns auth tokens and encrypts stored credentials. Never change it after the first deploy, or sessions and encrypted values break.
PAYLOAD_ADMIN_EMAILAdministrator created on first boot.
PAYLOAD_ADMIN_PASSWORDThat account's password. Change it once in.
DATABASE_URLPostgreSQL connection string.
S3_*Bucket credentials for uploads. Unset all to fall back to local disk, which no redeploy survives.
PAYLOAD_ROLEweb or jobs. Selects the container's role.
PAYLOAD_JOBS_CRONQueue drain schedule.
PAYLOAD_PUBLIC_SERVER_URLSet only for a custom domain; otherwise derived.
PAYLOAD_CORS_ORIGINSExtra browser origins allowed to call the API.

Deployment Dependencies

Hardware Requirements for Self-Hosting Payload

ResourceMinimumRecommended
CPU1 vCPU2 vCPU
RAM1 GB2 GB per app service
StorageDatabase only10 GB database plus object storage
RuntimeNode.js 20.9+Node.js 24

The build is heavier than the runtime — compiling the admin panel wants roughly 2 GB. Image resizing runs in the web service, so raise memory before CPU if you accept large uploads.

Self-Hosting Payload

Payload installs as a dependency of your own Next.js app rather than pulling as an image. To start a new project locally, run:

npx create-payload-app@latest my-cms
cd my-cms
npm run dev

To run this template's configuration yourself, clone the source repository and supply a database and a secret:

git clone https://github.com/gridalpha/payload-railway
cd payload-railway
npm install
export DATABASE_URL="postgres://user:pass@localhost:5432/payload"
export PAYLOAD_SECRET="a-long-random-string"
npm run build && npx payload migrate && npm start

Payload disables automatic schema syncing in production, so a change to a collection needs a migration committed alongside it. Generate one with npx payload migrate:create — it reads your config and needs no database connection.

How Much Does Payload Cost to Self-Host?

Payload is free and open source under the MIT licence, with no seat limits, content limits or feature paywall when self-hosted. The company sells Payload Cloud for managed hosting and an enterprise tier adding SSO and publishing workflows. On Railway you pay only for the compute, database and storage you use — a small site runs a few dollars a month, and cost scales with traffic rather than editor seats.

FAQ

What is Payload?

Payload is an open-source headless CMS and application framework for TypeScript and Next.js. You define the content schema in code and it generates an admin panel plus REST and GraphQL APIs from it.

Why does the template include PostgreSQL and object storage?

Payload keeps documents, drafts and version history in a relational database, so PostgreSQL is required rather than optional. Uploads need somewhere durable: container filesystems are replaced on every deploy, so local images would disappear.

Do I need the separate jobs worker service?

Only if you use scheduled publishing or define your own queued tasks, but it costs little and keeps that work off the request path. Payload's docs recommend this split for a dedicated server.

How do I add my own collections to a self-hosted Payload deployment?

Fork the repository, add a file under src/collections, register it in src/payload.config.ts, then run npx payload migrate:create and commit the migration. Pushing rebuilds both services and applies it.

Can I scale Payload beyond one instance?

Yes — the web service holds no local state, so raising its replica count is safe. Keep the jobs worker at one replica so scheduled tasks are not run twice. Frontends query /api/ for REST or /api/graphql; inside the same Next.js app the Local API skips HTTP entirely.


Template Content

More templates in this category

View Template
Libredesk - Complete Setup
Complete self-hosted omnichannel customer support desk.

codestorm
1
View Template
Paperless-ngx
Paperless-ngx — document management with OCR and full-text search

INAPP
1
View Template
Instatic CMS - Postgres
Design, build and manage powerful static sites from state-of-the-art CMS

Instatic
147