Railway

Deploy Payload CMS — Self-Hosted TypeScript Website Builder

Self-host Payload CMS — code-first website builder on Postgres

Deploy Payload CMS — Self-Hosted TypeScript Website Builder

/var/lib/postgresql/data

Just deployed

/app/public/media

Deploy and Host Payload CMS on Railway

Payload CMS is the open-source, TypeScript-native headless CMS and website builder — a code-first alternative to WordPress and Strapi, built directly on Next.js so your admin panel and front-end live in one app. This template is preconfigured as a website builder using PostgreSQL instead of Payload's default MongoDB, making it fully Railway-native. Based on the official Payload "website" starter, it ships with pages, blog posts, forms, user auth, and a comment system, so you deploy a complete, editable site in minutes.


What This Template Deploys

ServicePurpose
Payload CMSThe Next.js app — admin panel, front-end, REST + GraphQL API
PostgreSQLAll content, users, forms, and comments

Both connect over Railway's private network. Payload serves the admin panel at /admin, a REST API at /api, and GraphQL at /api/graphql. The template uses the Postgres adapter so no MongoDB is required.


About Hosting

Payload v3 is powerful, and two Railway-specific details decide whether it deploys cleanly — both handled here.

PostgreSQL instead of MongoDB — Railway-native. Payload defaults to MongoDB, but this template uses the @payloadcms/db-postgres adapter, so it runs on a standard Railway PostgreSQL service with no external Mongo to provision. That's the "preconfigured for Railway" difference: one database, wired through DATABASE_URI, fully managed on the platform.

The database must be reachable at build time. This is the trap that breaks most Payload-on-Railway deploys: because Payload v3 is built on Next.js, its static site generation connects to the database during the build, not just at runtime. If the build can't reach Postgres, you get getaddrinfo ENOTFOUND postgres.railway.internal and the build fails. This template wires the database reference so it's available at build time, so the first deploy completes instead of erroring.

Media needs S3 for persistence. Payload stores uploaded media on the local filesystem by default, which is ephemeral on Railway — images vanish on redeploy. For a production site, connect an S3-compatible bucket (Railway's storage or any S3 provider) via the storage plugin so uploads persist. Content, users, and forms live in Postgres and always persist; only media uploads need the bucket.

Set PAYLOAD_SECRET and the server URL. PAYLOAD_SECRET signs JWTs and secures Payload — set a strong value and keep it stable, or sessions break. NEXT_PUBLIC_SERVER_URL must be your Railway public domain so the admin panel generates correct links and API URLs. Both are configured at deploy.

Create your admin on first visit. After deploy, open /admin to create your first admin user, then optionally seed demo content to start from a working site with pages, posts, and forms rather than a blank install.

Typical cost: ~$5–15/month on Railway for the app and Postgres, plus object storage for media. Payload is MIT-licensed and free — no per-seat CMS fees.


How It Compares

Payload (self-hosted)WordPressStrapiContentful
ApproachCode-first (TypeScript)GUI + PHPGUI + configHosted SaaS
Front-endBuilt-in (Next.js)ThemesBring your ownBring your own
Type safetyFull TypeScriptNoPartialAPI-only
Cost modelFlat infraFlat infraFlat infraPer usage
Data ownershipFull — your infraFullFullVendor
Self-hostableYesYesYesNo

WordPress is ubiquitous but PHP-based and plugin-heavy. Strapi is a solid headless option but decouples the front-end. Contentful is polished but a paid SaaS that holds your content. Payload's edge is a code-first, fully type-safe CMS with the front-end built in via Next.js — versioned content models, full extensibility through code, and your content in your own Postgres, at flat cost.


Deploy in Under 5 Minutes

  1. Click Deploy on Railway — Payload and PostgreSQL build with the DB wired at build time (~4 minutes)
  2. Confirm PAYLOAD_SECRET is set and DATABASE_URI references your Postgres service
  3. Generate a domain and set NEXT_PUBLIC_SERVER_URL to it
  4. Open /admin, create your admin user, and optionally seed demo content
  5. Edit pages, posts, and forms, and connect an S3 bucket for persistent media uploads

Your site's front-end and the admin panel run from the same app, so you're live immediately.


Common Use Cases

  • Website and blog — a complete site with pages, posts, and forms, editable from the admin panel
  • Headless CMS backend — serve content to any front-end via REST and GraphQL APIs
  • Marketing sites — build and edit landing pages with a type-safe, developer-friendly CMS
  • Content-driven apps — model any content with full TypeScript type safety and version control
  • WordPress alternative — a modern, code-first CMS with the front-end built in via Next.js

Configuration

VariableRequiredDescription
DATABASE_URIAuto-injectedPostgreSQL connection — referenced so it's available at build time
PAYLOAD_SECRETRequiredSigns JWTs and secures Payload — set a strong, stable value
NEXT_PUBLIC_SERVER_URLRequiredYour Railway public domain — for admin links and API URLs
BUCKET_NAME / BUCKET_ACCESS_KEY_ID / BUCKET_SECRET_ACCESS_KEYOptionalS3 credentials for persistent media
BUCKET_ENDPOINTOptionalS3 endpoint for the storage provider

Set the secret and server URL. PAYLOAD_SECRET secures Payload — keep it stable, or sessions break. NEXT_PUBLIC_SERVER_URL must match your Railway domain for admin links to work.

Connect S3 for media. Uploads are ephemeral on Railway's filesystem — configure an S3-compatible bucket so media survives redeploys. Content in Postgres always persists.


Dependencies for Payload CMS Hosting

  • Railway account — ~$5–15/month for the app and Postgres, plus object storage
  • PostgreSQL (included and wired, with build-time access)
  • An S3-compatible bucket for persistent media (Railway storage or any S3 provider)
  • Node.js familiarity to customize collections in the code-first config

Deployment Dependencies

Implementation Details

The template deploys the official Payload "website" starter as a Next.js application backed by a Railway PostgreSQL service, using the @payloadcms/db-postgres adapter in place of Payload's default MongoDB so no external database is needed. It ships with collections for pages, posts, forms, users, and comments, and exposes the admin panel at /admin, a REST API at /api, and GraphQL at /api/graphql.

Because Payload v3 runs on Next.js, static generation requires database connectivity at build time — a common Railway failure (getaddrinfo ENOTFOUND postgres.railway.internal) when the build can't reach Postgres — so the template references the database connection such that it resolves during the build, not only at runtime. PAYLOAD_SECRET signs JWTs and must stay stable, and NEXT_PUBLIC_SERVER_URL is set to the Railway domain so the admin panel builds correct links.

Uploaded media defaults to the local filesystem, which is ephemeral on Railway, so an S3-compatible bucket is recommended via the storage plugin for persistent uploads; all other content persists in PostgreSQL, which is the component to back up. Note that this template tracks official Payload releases, so major updates may introduce schema changes requiring migrations.


Frequently Asked Questions

Why does the build fail with an ENOTFOUND Postgres error? Because Payload v3 is Next.js-based and its static generation connects to the database at build time. If Postgres isn't reachable during the build, it errors. This template wires the database reference so it's available at build time.

Why PostgreSQL instead of MongoDB? Payload defaults to MongoDB, but this template uses the Postgres adapter so it runs on a native Railway PostgreSQL service with nothing external to provision — the "Railway-compatible" difference.

Do my images persist? Content, users, and forms always persist in Postgres. Media uploads default to the local filesystem, which is ephemeral, so connect an S3-compatible bucket for persistent media.

How do I create my admin account? Open /admin after deploying to create your first admin user, then optionally seed demo content to start from a working site.

What's included out of the box? Pages, blog posts, forms, user authentication, and a comment system, based on Payload's official website starter — a complete, editable site rather than a blank CMS.

Is it a headless CMS or a website builder? Both — Payload is headless with REST and GraphQL APIs, and this template's website starter gives you a built-in Next.js front-end, so you can use it either way.


Why Deploy Payload CMS on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Payload CMS on Railway you get a complete website builder with the hard parts solved — PostgreSQL instead of MongoDB, the database wired for build-time access so deploys don't fail, the secret and server URL set, and automatic HTTPS. A code-first, type-safe CMS with the front-end built in, self-hosted on infrastructure you own.


Template Content

More templates in this category

View Template
Libredesk - Complete Setup
[Jul'26] Complete self-hosted omnichannel customer support desk.

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

Instatic
132
View Template
Strapi
A popular self-hosted CMS

Milo
7.7K