Skip to content

Deploying the API to Railway

Railway is a platform-as-a-service that deploys Node.js applications from a GitHub repo. It handles servers, scaling, and SSL automatically. (Referral link — signing up through it supports this platform at no cost to you.)

Make sure your project has:

  1. A start script in package.json:

    "scripts": {
    "start": "node dist/index.js",
    "build": "tsc"
    }
  2. A Procfile (optional but explicit):

    web: npm start
  3. Your dist/ directory is in .gitignore (Railway will build it).

  4. The app listens on process.env.PORT:

    const PORT = parseInt(process.env.PORT || '3000', 10)
    app.listen(PORT, ...)
  1. Push your code to GitHub.

  2. Go to railway.com and create a free account.

  3. Click New ProjectDeploy from GitHub repo → select your bulletin-api repository.

  4. Railway detects Node.js and automatically runs npm install && npm run build && npm start.

  5. Click on the deployment → SettingsVariables and add:

    NODE_ENV=production
    JWT_SECRET=<a long random string — never share this>
    DATABASE_PATH=./bulletin.db
    FRONTEND_URL=https://your-username.github.io
  6. In the Settings tab, generate a domain (e.g., bulletin-api-production.up.railway.app).

  7. Wait for the deployment to complete — check the build logs for errors.

Terminal window
# Health check
curl https://bulletin-api-production.up.railway.app/health
# → { "status": "ok" }
# Register a user
curl -X POST https://bulletin-api-production.up.railway.app/auth/register \
-H "Content-Type: application/json" \
-d '{"username": "testuser", "password": "testpassword"}'
# → { "token": "eyJ...", "userId": 1, "username": "testuser" }

SQLite works on Railway but with one limitation: the database file (bulletin.db) is stored on the container’s filesystem. If Railway restarts the container (which it does occasionally), the database persists IF it’s in the project directory committed to git — but it usually isn’t (databases aren’t committed to git).

For a learning project, this is fine. For production apps, you’d use a persistent database service (Railway PostgreSQL, PlanetScale, Supabase, etc.).

Add your bulletin.db to .gitignore and accept that the database may reset on deployment. For learning purposes, this is perfectly acceptable.

Every push to your GitHub main branch triggers a new deployment automatically.

VariableValue
NODE_ENVproduction
JWT_SECRETLong random string (never commit)
DATABASE_PATH./bulletin.db
FRONTEND_URLYour GitHub Pages URL
PORTSet automatically by Railway
  1. Push your bulletin-api project to GitHub.
  2. Deploy to Railway following the steps above.
  3. Set all environment variables.
  4. Test POST /auth/register against the live URL.
  5. Note the Railway API URL — you’ll use it in Part 2 to configure the React frontend.
  • Railway deploys Node.js apps from GitHub repos — auto-detects, auto-builds.
  • PORT is set by Railway — use process.env.PORT in your app.
  • Set environment variables (JWT_SECRET, FRONTEND_URL) in the Railway dashboard.
  • SQLite persists as long as the container doesn’t restart — acceptable for learning, use a managed DB for production.
  • Save your Railway URL — the React frontend needs it in Module 08.