---
title: "Deploy WordPress Headless"
description: "WordPress REST API backend for a Next.js frontend"
category: "CMS"
url: https://railway.com/deploy/deploy-headless-wordpress-for-nextjs
---

# Deploy WordPress Headless

WordPress REST API backend for a Next.js frontend

**[Deploy WordPress Headless on Railway](https://railway.com/template/deploy-headless-wordpress-for-nextjs)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/deploy-headless-wordpress-for-nextjs/manifest.json

- **Creator:** onepush
- **Category:** CMS

## Template content

### WordPress

- **Image:** ghcr.io/onepush-dev/wordpress:7.1.3-php8.4@sha256:1cb7b95a5ce4ed01189fb44773773ea38ec5c5c56b0ca534f98435bda1725067
- **Health check:** /healthz
- **Public domain:** Yes

### Valkey

- **Image:** valkey/valkey:9.1.2-alpine@sha256:48332870af354a799964c0012ae1194a0bf2bf894eb508f945810596dc2d8d11
- **Start command:** `/bin/sh -c 'exec docker-entrypoint.sh valkey-server --requirepass "$VALKEY_PASSWORD" --maxmemory "${VALKEY_MAXMEMORY:-256mb}" --maxmemory-policy allkeys-lru --save "" --appendonly no'`

### MariaDB

- **Image:** mariadb:12.3.3@sha256:99c125f103f5d081ebbc9ffe064e63daf7f688ac33a5f7f29af2d7260a96debf
- **Start command:** `/bin/sh -c 'exec docker-entrypoint.sh mariadbd --innodb-buffer-pool-size="${MARIADB_INNODB_BUFFER_POOL_SIZE:-256M}" --max-allowed-packet=64M --skip-name-resolve'`

## Documentation

# Deploy and Host self hosted WordPress Headless (Open-Source Headless CMS) on Railway

This template runs WordPress 7.1.3 on PHP 8.4 with OPcache, a Valkey object cache and MariaDB as a headless CMS for Next.js. Editors keep wp-admin, developers keep React, and content comes out of /wp-json/wp/v2/.

## About Hosting WordPress Headless open-source software on Railway (self hosted headless WordPress template)

You own the content: posts, pages and media live in MariaDB and the /var/www/html volume, not in a vendor dashboard, so a database dump plus the uploads folder is the whole backup story.

This template runs WordPress 7.1.3 on PHP 8.4 with OPcache, a Valkey object cache drop-in and MariaDB 12.3.3, fronted by the REST API at /wp-json/wp/v2/. Railway handles the domain, TLS, deploys and service wiring, so your Next.js app fetches JSON while editors stay in wp-admin.

## Why Deploy WordPress Headless, the Strapi alternative on Railway (Railway Free Trial)

Strapi means another Node service and admin panel to patch, plus a content model defined in code. Here WordPress is already installed, so editors keep wp-admin while Next.js reads /wp-json. Spin it up on the $5 Railway trial and time the REST calls yourself.

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 WordPress Headless on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

### Railway vs Other Hosting Providers and VPS for WordPress Headless self hosting

Railway ships the whole headless stack as one project.

| Provider | What You Get with Railway | What You Get with the Other Provider |
| --- | --- | --- |
| DigitalOcean | WordPress, MariaDB and Valkey in one project, variables defaulted. | Droplets or App Platform where you install the image, database and cache yourself. |
| AWS | Pinned image, /healthz checks and a volume at /var/www/html for uploads. | Lightsail or EC2 plus RDS and ElastiCache, with VPC, backups and patching on you. |
| Hetzner | Usage-based capacity and push-to-deploy, with the wiring already done. | Cheap fast VMs, but a bare box: stack, TLS and database dumps are yours. |

The Next.js frontend stays yours either way.

## Common Use Cases for hosted WordPress Headless

- **Next.js marketing site with editors in wp-admin:** editors keep the familiar WordPress editor and publish, while the React frontend pulls pages and posts from /wp-json/wp/v2/ in server components.
- **Blog inside an existing React app:** fetch posts with per_page and _embed, cache with revalidate 60, and revalidate on publish through a protected route handler.
- **One backend, several frontends:** a marketing site, docs, and a mobile app all read the same REST routes, so content is entered once.
- **Draft previews:** Application Passwords let the server fetch unpublished posts so writers can review before going live.
- **Gradual theme migration:** run the WordPress theme and the Next.js site side by side, moving templates over one route at a time.

## Dependencies for WordPress Headless Docker hosted on Railway

Railway creates three services: WordPress, MariaDB 12.3.3, and Valkey 9.1.2. The WordPress image is pinned by digest, so redeploys don't move PHP or core under you. All 32 variables ship with defaults; in practice you only edit WP_HOME after adding a custom domain.

### Deployment Dependencies for Managed WordPress Headless Service (Headless CMS)

WordPress listens on port 80, answers health checks at /healthz, and keeps a volume at /var/www/html for core, themes, plugins, and uploads. Valkey has no volume on purpose, since losing a cache on restart costs nothing. WORDPRESS_DB_HOST and WP_REDIS_HOST already reference the other services.

### Implementation Details for WordPress Headless (Using WordPress official docker image)

The container runs PHP 8.4 with a 256 MB OPcache and the Redis Object Cache drop-in over phpredis and igbinary. Setting WP_REDIS_DISABLED to true turns that off. Uploads stay on the WordPress domain unless you offload to S3, so Next.js should reference absolute media URLs, not relative paths.

## How does WordPress Headless compare against other headless CMS options

### WordPress vs Strapi (Strapi Alternative)

- **Editors:** wp-admin is already familiar; Strapi means learning a new admin.
- **Schema:** Strapi keeps content types in code, so migrations are cleaner.
- **API:** Both do REST; WordPress ships /wp-json/wp/v2/ with no modeling step.
- **Strapi wins:** strict schemas and commit-ready migrations.

### WordPress vs Contentful (Contentful Alternative)

- **Hosting:** Contentful is SaaS only; here posts, media and MariaDB sit on your volume.
- **Modeling:** Contentful's content model UI and SDKs are better than WordPress plus ACF.
- **Lock-in:** WordPress data is tables plus uploads you can dump and move.
- **Contentful wins:** nothing to patch, and a CDN included.

### WordPress vs Sanity (Sanity Alternative)

- **Storage:** Sanity serves documents from a hosted dataset over GROQ; WordPress serves MariaDB rows over REST or WPGraphQL.
- **Body copy:** Sanity's portable text is typed and reusable; WordPress returns rendered HTML.
- **Collab:** Sanity does real-time co-editing; WordPress gives revisions and previews.
- **Sanity wins:** an API-first stack where schema and editor fit together.

### WordPress vs Ghost (Ghost Alternative)

- **Scope:** Ghost is publishing plus memberships; WordPress adds custom post types, media and plugins.
- **Drafts:** Ghost's Content API is read-only, so writes take the admin API; WordPress previews work with an Application Password from your server.
- **Ghost wins:** less to operate, and email built in without plugins.

## How to use WordPress Headless (the OSS CMS)?

1. Open your Railway domain and finish the WordPress installer, then set Settings > Permalinks to Post name.
2. Load https://your-domain/wp-json/wp/v2/posts and confirm you get JSON back.
3. Under Users > Profile, create an Application Password; send it as Basic auth from the server only.
4. Fetch posts in a Next.js server component:

```ts
const res = await fetch(url, { next: { revalidate: 60 } });
```

5. Add a route handler that checks a secret, calls revalidatePath('/blog'), and is hit by a publish webhook:

```bash
curl -X POST https://your-site/api/revalidate?secret=$SECRET
```

6. Keep wp-admin for editors; the Next.js site stays public.

## How to self host WordPress Headless on other VPS Services (WordPress self hosting guide)

A small VPS runs the same three pieces: WordPress, MariaDB and Valkey behind a proxy.

### Clone the Repository

Pull the pinned image, or clone the repo that builds it:

```bash
docker pull ghcr.io/onepush-dev/wordpress:7.1.3-php8.4
```

### Install Dependencies

Install Docker with the compose plugin, write a compose file with the three services and their volumes, open ports 80 and 443, and point your-domain at the box with an A record.

### Configure Environment Variables

Set WP_HOME to https://your-domain, the WORDPRESS_DB_* values pointing at MariaDB, the salts, and WP_REDIS_HOST plus WP_REDIS_PASSWORD for Valkey.

### Start the WordPress Headless Application

```bash
docker compose up -d
```

Finish the installer, set Settings > Permalinks to Post name, then fetch https://your-domain/wp-json/wp/v2/posts from a Next.js server component.

Railway provisions WordPress, MariaDB and Valkey together, wires the credentials, and issues HTTPS on your-domain.

## Official Pricing of WordPress Headless (WordPress pricing)

WordPress core is free under GPLv2, so the license costs nothing. MariaDB and Valkey run as services in the same project, so the database and object cache share that one usage bill. Editors work in wp-admin either way, and the Next.js frontend is your own hosting bill.

## WordPress Headless cloud vs self hosted comparison (Pricing, features, costs, and more)

Railway bundles the three services, so the cost question is one bill rather than three. Here is how that compares with a VPS you patch.

### Monthly cost of self hosting WordPress Headless on Railway

About $5-20/mo for a small to medium site, depending on traffic and RAM. That covers the WordPress service, MariaDB and the Valkey object cache, and the $5 trial gets you started.

### System Requirements for Hosting WordPress Headless on a VPS

Plan on 512 MB to 1 GB RAM for WordPress plus MariaDB, with Valkey capped at 256 MB. Any host that gives you a Docker runtime and a MariaDB connection string will run the same stack.

## Frequently Asked Questions (FAQs)

### Do I need WPGraphQL?

No. REST ships in core and covers posts, pages, categories, tags, media, and users. Add WPGraphQL only if your frontend already speaks GraphQL or you need one query for deeply nested fields.

### Why does /wp-json return 404?

Almost always plain permalinks. Set Settings > Permalinks to Post name, and https://your-domain/wp-json/wp/v2/posts resolves. Until then use https://your-domain/?rest_route=/wp/v2/posts.

### How do I show drafts in Next.js?

Send an Application Password as Basic auth from the server only, never from the browser. Create one under Users > Profile and keep it in a server-side env var.

### Do I need CORS?

Only for browser-side calls to /wp-json. Server components and route handlers fetch from Node, so no CORS headers are needed.

### How do updates appear without a rebuild?

Hit a route handler that calls revalidatePath or revalidateTag, triggered by a WordPress publish hook or webhook plugin. Or lean on time-based revalidation, for example revalidate: 60.

### Where are images served from?

wp-content/uploads on the WordPress volume, so media URLs point at your WordPress domain. Offload to S3 if you want them behind a CDN.


## Similar templates

- [Libredesk - Complete Setup](https://railway.com/deploy/libredesk-complete-setup) — Complete self-hosted omnichannel customer support desk.
- [Paperless-ngx](https://railway.com/deploy/paperless-ngx-3) — Paperless-ngx — document management with OCR and full-text search
- [Instatic CMS - Postgres](https://railway.com/deploy/instatic-cms-postgres) — Design, build and manage powerful static sites from state-of-the-art CMS

Open this page in a browser: https://railway.com/deploy/deploy-headless-wordpress-for-nextjs
