What you'll build

In this final part you'll take the API from your laptop to a live public URL. Railway handles the server, the build pipeline, and automatic deployments on every Git push.

By the end of this part your API will be:

Prepare the project for deployment

Add a Procfile in the project root:

web: node dist/index.js

Verify your package.json scripts:

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "nodemon --exec ts-node src/index.ts --ext ts"
  }
}

Make sure dist/ is in .gitignore so you don't commit compiled files:

echo "dist/" >> .gitignore

Push to GitHub

git init
git add .
git commit -m "Initial API"

Create a repo at github.com/new (name: product-catalog-api), then push:

git remote add origin https://github.com/your-username/product-catalog-api.git
git branch -M main
git push -u origin main

Deploy on Railway

  1. Go to railway.app and sign in with GitHub
  2. Click New Project → Deploy from GitHub repo
  3. Select product-catalog-api
  4. Railway detects Node.js, runs npm run build, then npm start
  5. After the first deploy completes, go to Settings → Domains → Generate Domain

You'll get a URL like https://product-catalog-api-production.up.railway.app.

Set environment variables

In Railway, go to your service and click Variables. Add each variable:

Variable Value
JWT_SECRET A long random string (generate with openssl rand -base64 32)
SUPABASE_URL Your Supabase project URL
SUPABASE_SERVICE_KEY Your Supabase service_role key
PAYSTACK_SECRET_KEY Your Paystack secret key

Railway sets PORT automatically — do not add it manually.

After saving variables, Railway redeploys. Watch the build log to confirm it completes without errors.

Update Paystack webhook URL

In the Paystack dashboard, go to Settings → API Keys & Webhooks and update the Webhook URL to your Railway URL:

https://your-app.up.railway.app/webhooks/paystack

Smoke test the live API

BASE=https://your-app.up.railway.app

# Health check
curl $BASE/health

# Register a user
curl -X POST $BASE/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"securepassword","name":"Live User"}'

# Login
curl -X POST $BASE/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"securepassword"}'

# List products (should return data from Supabase)
curl $BASE/products

Free tier limits: Railway's free hobby plan gives each service 500 execution hours per month — enough for a small production app. If you're building something high-traffic, upgrade to the Pro plan or switch to a VPS. Supabase's free tier gives you 500MB storage and 2GB bandwidth per month, which is plenty to get started.

Automatic deployments

Every time you push to main, Railway will rebuild and redeploy your API automatically. You'll see the deploy status in the Railway dashboard. Zero-downtime deploys are handled by Railway — the old version keeps serving traffic until the new one is ready.

What you've built

Over this five-part series you've built a production REST API with:

This API is a solid foundation you can extend for any product — add more resource types, add an admin role check, or connect it to a React or Flutter frontend from the other tutorial series on this site.