← Back to articles

How to Deploy Strapi on Railway with PostgreSQL from Scratch

Slug: deploy-strapi-railway-postgresql

How to Deploy Strapi on Railway with PostgreSQL from Scratch

This guide explains how to create a Strapi project locally, push it to GitHub, deploy it on Railway, connect it to PostgreSQL, and access the Strapi admin panel online.

It is written for developers who want to use Strapi as a CMS backend for a Next.js website, technical blog, AI directory, or content-driven project.

Final Architecture

The final setup looks like this:


Frontend website:

aiseocode.com



Strapi CMS:

cms.aiseocode.com or Railway temporary domain



Backend hosting:

Railway



Database:

Railway PostgreSQL



Code repository:

GitHub

For a Next.js content website, a common production setup is:


Next.js frontend → Vercel

Strapi CMS → Railway

Database → Railway PostgreSQL

Media storage → Cloudflare R2, S3, or Cloudinary

Step 1: Check Node.js and npm

First, check your local Node.js and npm versions:


node -v

npm -v

git --version

Strapi 5 requires a supported Node.js version. If your Node.js version is too new, for example Node 25, Strapi may fail to create or run the project.

A safe choice is Node.js 22 LTS.

If you use nvm, install and switch to Node.js 22:


nvm install 22

nvm use 22

nvm alias default 22

Then confirm:


node -v

npm -v

You should see a Node.js version similar to:


v22.x.x

Step 2: Create a Local Strapi Project

Create a new Strapi project:


npx create-strapi-app@latest aiseocode-cms

During the setup, choose:


Login or sign up: Skip

Default database sqlite: Yes

Example structure and data: No

TypeScript: Yes

Install dependencies with npm: Yes

Initialize a git repository: Yes

For local development, SQLite is fine. Later, Railway will use PostgreSQL.

After installation, go into the project directory:


cd aiseocode-cms

Start Strapi locally:


npm run develop

Open the local admin panel:


http://localhost:1337/admin

Create your first local admin account.

Step 3: Push the Project to GitHub

After confirming Strapi works locally, commit the project:


git add .

git commit -m "init aiseocode strapi cms"

git branch -M main

Create a new GitHub repository, for example:


aiseocode-cms

Do not initialize the GitHub repository with a README, .gitignore, or license if your local repository already exists.

Then connect your local project to GitHub:


git remote add origin https://github.com/your-username/aiseocode-cms.git

git push -u origin main

Step 4: Install PostgreSQL Driver

Railway will use PostgreSQL in production, so install the PostgreSQL driver:


npm install pg

Commit and push the change:


git add .

git commit -m "add postgres driver"

git push

Step 5: Configure Strapi Database for Railway

Open the Strapi database configuration file:


nano config/database.ts

Replace the content with:


import path from 'path';



export default ({ env }) => {

  const client = env('DATABASE_CLIENT', 'sqlite');



  const connections = {

    postgres: {

      connection: {

        connectionString: env('DATABASE_URL'),

        host: env('DATABASE_HOST'),

        port: env.int('DATABASE_PORT'),

        database: env('DATABASE_NAME'),

        user: env('DATABASE_USERNAME'),

        password: env('DATABASE_PASSWORD'),

        ssl: env.bool('DATABASE_SSL', false)

          ? {

              rejectUnauthorized: env.bool('DATABASE_SSL_REJECT_UNAUTHORIZED', false),

            }

          : false,

      },

      pool: {

        min: env.int('DATABASE_POOL_MIN', 2),

        max: env.int('DATABASE_POOL_MAX', 10),

      },

    },



    sqlite: {

      connection: {

        filename: path.join(

          __dirname,

          '..',

          '..',

          env('DATABASE_FILENAME', '.tmp/data.db')

        ),

      },

      useNullAsDefault: true,

    },

  };



  return {

    connection: {

      client,

      ...connections[client],

      acquireConnectionTimeout: env.int('DATABASE_CONNECTION_TIMEOUT', 60000),

    },

  };

};

This configuration allows:


Local development: SQLite

Railway production: PostgreSQL

Save the file, then test locally:


npm run develop

If it works, stop the server with:


Control + C

Then commit and push:


git add .

git commit -m "configure database for railway postgres"

git push

Step 6: Deploy Strapi on Railway

Go to Railway and create a new project.

Choose:


New Project

→ GitHub Repository

→ Select your Strapi repository

→ Deploy

Railway will pull your GitHub project and start building it.

At first, the service may crash because environment variables and PostgreSQL are not configured yet. This is normal.

Step 7: Add PostgreSQL on Railway

Inside the same Railway project, click:


+ Add

→ Database

→ PostgreSQL

After adding PostgreSQL, the Railway project should have two services:


aiseocode-cms

Postgres

Step 8: Add Environment Variables

Open the Strapi service:


aiseocode-cms

→ Variables

Add the following variables:


NODE_ENV=production

HOST=0.0.0.0

PORT=1337



DATABASE_CLIENT=postgres

DATABASE_URL=${{Postgres.DATABASE_URL}}

DATABASE_HOST=${{Postgres.PGHOST}}

DATABASE_PORT=${{Postgres.PGPORT}}

DATABASE_NAME=${{Postgres.PGDATABASE}}

DATABASE_USERNAME=${{Postgres.PGUSER}}

DATABASE_PASSWORD=${{Postgres.PGPASSWORD}}

DATABASE_SSL=false

DATABASE_SSL_REJECT_UNAUTHORIZED=false

If your PostgreSQL service is not named Postgres, replace Postgres with the actual service name.

Step 9: Add Strapi Secret Keys

Strapi also requires security keys.

Generate random keys locally:


openssl rand -base64 32

Run the command multiple times and fill these Railway variables:


APP_KEYS=key1,key2,key3,key4

API_TOKEN_SALT=key5

ADMIN_JWT_SECRET=key6

TRANSFER_TOKEN_SALT=key7

JWT_SECRET=key8

ENCRYPTION_KEY=key9

Important rules:


APP_KEYS should contain multiple keys separated by English commas.

Do not use quotes.

Do not keep placeholder values such as "tobemodified".

Step 10: Apply Changes and Redeploy

After adding variables, Railway may show:


Apply changes

Click it and deploy the changes.

Wait until the service status becomes:


Online

Step 11: Open the Strapi Admin Panel

Generate a public Railway domain from:


Settings

→ Networking

→ Generate Domain

Then open:


https://your-railway-domain.up.railway.app/admin

If you see the Strapi admin registration page, the deployment is successful.

Create the production admin account.

Your local admin account and Railway admin account are separate because they use different databases.

Step 12: Create an Article Content Type Locally

Strapi content types should be created locally in development mode, then committed to GitHub.

Start Strapi locally:


cd /Users/your-name/aiseocode-cms

npm run develop

Open:


http://localhost:1337/admin

Go to:


Content-Type Builder

→ Create new collection type

Create:


Display name: Article

Enable Internationalization if your project needs multiple languages.

Step 13: Add Article Fields

Create these fields:


title

slug

content

Recommended settings:

| Field | Type | Required | Unique | Localization |

|---|---|---:|---:|---:|

| title | Text | Yes | No | Yes |

| slug | Text | Yes | Yes | Yes |

| content | Rich Text | Yes | No | Yes |

Use Text for slug if you want to write the slug manually.

Do not use UID if you do not want Strapi to generate the slug from the title.

For the slug field, you may add this regular expression:


^[a-z0-9]+(?:-[a-z0-9]+)*$

This allows slugs like:


deploy-strapi-railway-postgresql

nextjs-strapi-blog

ai-seo-tools

Step 14: Add Chinese Locale

In Strapi, go to:


Settings

→ Internationalization

→ Locales

→ Add new locale

Choose:


Chinese (Simplified, China) (zh-CN)

Keep:


Set as default locale: false

The recommended language structure is:


Default language: English

Chinese language: zh-CN

Your frontend URL structure can be:


English:

https://aiseocode.com/article/deploy-strapi-railway-postgresql



Chinese:

https://aiseocode.com/zh-cn/article/deploy-strapi-railway-postgresql-zh-cn

Step 15: Commit the Article Content Type

After saving the content type locally, stop Strapi:


Control + C

Then commit and push:


git status

git add .

git commit -m "add article content type and zh-cn locale"

git push

Railway will automatically redeploy.

After deployment, the online Strapi admin should show the Article collection type.

Step 16: Create a Test Article Online

Open the online Strapi admin:


https://your-railway-domain.up.railway.app/admin

Go to:


Content Manager

→ Article

→ Create new entry

Create an English article:


title: Test Article

slug: test-article

content: This is a test article.

Save and publish it.

Step 17: Enable Public API Access

If the API returns permission errors, go to:


Settings

→ Users & Permissions Plugin

→ Roles

→ Public

Enable these permissions for Article:


find

findOne

Save.

Then test:


https://your-railway-domain.up.railway.app/api/articles

If JSON data appears, Strapi is working correctly.

Step 18: Bind a Custom Domain

After the Railway temporary domain works, bind:


cms.aiseocode.com

In Railway:


Settings

→ Networking

→ Custom Domain

Add:


cms.aiseocode.com

Then go to your DNS provider and add the CNAME or TXT records Railway provides.

After DNS verification, your Strapi CMS will be available at:


https://cms.aiseocode.com/admin

Common Errors and Fixes

Error: Could not read package.json

This means you are not inside the Strapi project directory.

Fix:


cd /Users/your-name/aiseocode-cms

npm run develop

Error: Unsupported Node.js version

If Strapi says Node.js is not supported, switch to Node.js 22:


nvm install 22

nvm use 22

Error: App keys are required

This means APP_KEYS is missing in Railway.

Fix by adding:


APP_KEYS=key1,key2,key3,key4

Error: Application failed to respond

Check:


Railway Deployments → Logs

Common causes include:


Missing environment variables

Database connection error

Service not redeployed after variable changes

Wrong port

Final Result

After completing all steps, you will have:


A local Strapi development environment

A GitHub repository

A Railway Strapi production deployment

A Railway PostgreSQL database

A working Strapi admin panel

An Article content type

English and Chinese locale support

A future CMS backend for a Next.js website

This setup is suitable for a technical blog, AI SEO website, AI code resource site, or multilingual content platform.