How to Deploy Node.js App on Railway: A Complete Guide

We earn commissions when you shop through the links below.

If you’ve been looking for the fastest way to get a Node.js backend live without wrestling with server configs, this guide walks you through exactly how to deploy Node.js app on Railway — from zero to a running URL in under ten minutes. Railway has become one of my go-to platforms for side projects and client work because it genuinely gets out of your way.

Why Railway?

Railway is a platform-as-a-service (PaaS) that handles infrastructure so you don’t have to. You push code, Railway builds and runs it. There’s no Dockerfile required (though you can use one), no Nginx config, no SSH sessions. For Node.js apps specifically, Railway auto-detects your runtime, installs dependencies, and starts your server using the start script in your package.json.

Compared to alternatives like DigitalOcean App Platform or Heroku, Railway tends to be faster to set up and more generous on the free tier for small projects. It also has first-class support for databases, environment variables, and private networking between services.

Prerequisites

  • A Node.js app with a package.json
  • Your code pushed to a GitHub repository
  • A Railway account (free to sign up at railway.app)

Step 1: Prepare Your Node.js App

Railway looks for a start script in your package.json to know how to run your app. Make sure yours looks something like this:

{
  "name": "my-api",
  "version": "1.0.0",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}

Your app also needs to listen on the port Railway provides via the PORT environment variable. This is critical — if you hardcode port 3000, Railway won’t be able to route traffic to your app.

const express = require('express');
const app = express();

const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({ status: 'ok', message: 'Hello from Railway!' });
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

That process.env.PORT pattern is the single most common reason deployments fail on PaaS platforms. Get this right first.

Step 2: Push Your Code to GitHub

Railway deploys directly from GitHub (or GitLab). If your project isn’t already in a repo, initialize one and push:

git init
git add .
git commit -m "initial commit"
git remote add origin https://github.com/yourusername/my-api.git
git push -u origin main

Every time you push to your connected branch, Railway will automatically trigger a new deployment. This is the CI/CD pipeline you get for free.

Step 3: Create a Railway Project

  1. Log in to railway.app and click New Project.
  2. Select Deploy from GitHub repo.
  3. Authorize Railway to access your GitHub account if prompted.
  4. Pick the repository you just pushed.
  5. Railway will immediately start detecting your project and building it.

You’ll see a build log in real time. For a basic Express app, the build usually completes in 30–60 seconds. Railway detects Node.js automatically, runs npm install, and then executes your start script.

Step 4: Set Environment Variables

If your app uses environment variables (API keys, database URLs, JWT secrets), add them in Railway before your first deploy completes — or add them and redeploy.

  1. Go to your service inside the project.
  2. Click the Variables tab.
  3. Add key-value pairs. Railway injects these as real environment variables at runtime.

Never commit .env files to your repo. Railway’s variable management is the right place for secrets.

# Example variables you might add in Railway
NODE_ENV=production
JWT_SECRET=your-super-secret-key
DATABASE_URL=postgresql://user:password@host:5432/dbname

If you’re adding a PostgreSQL database to the same Railway project, Railway automatically injects DATABASE_URL into your app service — no copy-pasting connection strings needed.

Step 5: Add a Database (Optional)

One of Railway’s best features is one-click databases. Inside your project:

  1. Click NewDatabase.
  2. Choose PostgreSQL, MySQL, MongoDB, or Redis.
  3. Railway spins up the database and links the connection URL to your app service automatically.

This is significantly easier than provisioning a separate managed database on another platform and manually wiring up the credentials.

Step 6: Get a Public URL

By default, your Railway service runs internally. To expose it to the internet:

  1. Go to your service → Settings tab.
  2. Under Networking, click Generate Domain.
  3. Railway gives you a *.up.railway.app subdomain instantly.

You can also add a custom domain here. Point your DNS CNAME to Railway’s value and they handle SSL automatically via Let’s Encrypt. Custom domains are available on the Hobby plan and above.

Step 7: Verify the Deployment

Hit your Railway URL in a browser or with curl:

curl https://my-api.up.railway.app/
# Expected output:
# {"status":"ok","message":"Hello from Railway!"}

If something went wrong, check the Deployments tab for build logs and the Logs tab for runtime output. 90% of issues are either the PORT variable or a missing dependency in package.json.

Continuous Deployment in Practice

Once connected, your workflow becomes dead simple:

# Make a change locally
git add .
git commit -m "add new endpoint"
git push origin main
# Railway automatically builds and deploys

Railway watches your connected branch and redeploys on every push. You can also trigger manual deployments or roll back to a previous deployment from the Railway dashboard — which is a lifesaver when a bad commit sneaks through.

Using a Dockerfile (Advanced)

If you need more control — specific Node version, build steps, or a monorepo setup — you can add a Dockerfile to your repo root and Railway will use it instead of its auto-detection:

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000

CMD ["node", "index.js"]

Even with a Dockerfile, Railway still injects the PORT environment variable, so make sure your app reads from it rather than hardcoding the EXPOSE value.

Railway Pricing

Railway’s free tier gives you $5 of compute credit per month, which is enough for a low-traffic hobby project. The Hobby plan at $5/month removes the credit cap and adds custom domains. Pro plans scale for teams and production workloads. For most side projects and MVPs, the Hobby plan is the sweet spot.

When to Choose Railway vs Alternatives

Railway is my default recommendation when you want deployment simplicity and integrated databases for Node.js apps. If you need more raw control over your infrastructure, VPS options like DigitalOcean Droplets make more sense. If you’re looking to learn Node.js deployment concepts from scratch, Udemy has solid courses covering everything from basics to production deployment patterns.

Final Thoughts

Knowing how to deploy Node.js app on Railway is genuinely one of those skills that pays back immediately. The platform removes nearly all the friction between writing code and having it live on the internet. For solo developers and small teams shipping fast, that matters a lot.

The whole process — connect GitHub, set env vars, generate a domain — takes less time than writing this article. If you’re still manually SSHing into servers to deploy Node.js apps, give Railway a serious look.