Skip to main content
This guide covers deploying both the Highway backend and frontend to production environments.

Prerequisites

Before deploying, ensure you have:
1

Production environment variables

  • OpenAI API key with production access
  • Twilio account with verified phone number
  • Supabase project configured
  • Domain name (optional but recommended)
2

SSL certificates

  • WebSocket connections require HTTPS/WSS
  • Use a service like Let’s Encrypt for free SSL
  • Or use a platform that provides SSL automatically
3

Tested build

  • Test backend locally: node index.js
  • Test frontend build: npm run build && npm run start
  • Verify all features work correctly

Backend Deployment

The Highway backend can be deployed to various platforms:

Option 1: Railway

Railway provides easy deployment with automatic SSL and environment variable management.
1

Install Railway CLI

npm i -g @railway/cli
2

Login and initialize

railway login
cd highway-backend
railway init
3

Add environment variables

railway variables set OPENAI_API_KEY=sk-proj-...
railway variables set PORT=8080
railway variables set TWILIO_ACCOUNT_SID=AC...
railway variables set TWILIO_AUTH_TOKEN=...
railway variables set TWILIO_PHONE_NUMBER=+1...
4

Deploy

railway up
Railway will provide a URL like https://your-app.railway.app

Option 2: Render

Render offers free tier for backend services.
1

Create new Web Service

  1. Go to Render Dashboard
  2. Click “New +” → “Web Service”
  3. Connect your GitHub repository
  4. Select highway-backend directory
2

Configure service

Build Command: npm installStart Command: node index.jsEnvironment: Node
3

Add environment variables

In the Render dashboard, add all backend environment variables:
  • OPENAI_API_KEY
  • PORT (Render provides this automatically)
  • TWILIO_ACCOUNT_SID
  • TWILIO_AUTH_TOKEN
  • TWILIO_PHONE_NUMBER
4

Deploy

Click “Create Web Service” and Render will deploy automatically.

Option 3: DigitalOcean App Platform

1

Create new app

  1. Go to DigitalOcean Apps
  2. Click “Create App”
  3. Connect your GitHub repository
  4. Select the highway-backend directory
2

Configure build settings

Run Command: node index.jsHTTP Port: 8080 (or your configured PORT)
3

Add environment variables

Add all required backend environment variables in the app settings.
4

Deploy

Review and create the app. DigitalOcean will build and deploy.

Backend Deployment Considerations

WebSocket Support RequiredEnsure your deployment platform supports:
  • WebSocket connections (required for Twilio media streams)
  • Long-running connections
  • WSS (WebSocket Secure) protocol
Platform Requirements:
  • Node.js 18+ runtime
  • WebSocket support (not all platforms support this)
  • Ability to listen on custom ports
  • HTTPS/WSS for production
Recommended Platforms:
  • ✅ Railway (excellent WebSocket support)
  • ✅ Render (supports WebSockets)
  • ✅ DigitalOcean App Platform
  • ✅ AWS EC2 / Elastic Beanstalk
  • ✅ Google Cloud Run
  • ⚠️ Vercel (limited WebSocket support)
  • ⚠️ Netlify (no WebSocket support for functions)

Frontend Deployment

The Highway frontend (Next.js) can be deployed to platforms optimized for React apps: Vercel is created by the Next.js team and offers the best integration.
1

Install Vercel CLI

npm i -g vercel
2

Login and deploy

cd highway-frontend
vercel
Follow the prompts to configure your project.
3

Add environment variables

In the Vercel dashboard:
  1. Go to Project Settings → Environment Variables
  2. Add NEXT_PUBLIC_SUPABASE_URL
  3. Add NEXT_PUBLIC_SUPABASE_ANON_KEY
  4. Add NEXT_PUBLIC_BACKEND_URL (your deployed backend URL)
4

Deploy to production

vercel --prod
Vercel will provide a production URL like https://your-app.vercel.app

Option 2: Netlify

1

Install Netlify CLI

npm i -g netlify-cli
2

Build the project

cd highway-frontend
npm run build
3

Deploy

netlify deploy --prod
Select .next as the publish directory.
4

Configure environment variables

In Netlify dashboard:
  • Site Settings → Environment Variables
  • Add all NEXT_PUBLIC_* variables

Option 3: Self-Hosted

Deploy to your own server:
1

Build the application

cd highway-frontend
npm run build
2

Start the production server

npm run start
Or use PM2 for process management:
npm i -g pm2
pm2 start npm --name "highway-frontend" -- start
pm2 save
pm2 startup
3

Configure reverse proxy

Use Nginx or Apache to proxy requests:
nginx.conf
server {
  listen 80;
  server_name your-domain.com;
  
  location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}
4

Add SSL certificate

sudo certbot --nginx -d your-domain.com

Environment Variable Management

Production Environment Variables

Backend (.env):
OPENAI_API_KEY=sk-proj-production-key
PORT=8080
TWILIO_ACCOUNT_SID=AC...
TWILIO_AUTH_TOKEN=...
TWILIO_PHONE_NUMBER=+1...
Frontend (.env.production):
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
NEXT_PUBLIC_BACKEND_URL=https://api.your-domain.com

Secrets Management Best Practices

1

Use platform secret management

  • Most platforms encrypt environment variables
  • Use platform UI to set sensitive values
  • Never commit production secrets to Git
2

Separate environments

  • Development: .env.development
  • Staging: .env.staging
  • Production: .env.production
3

Rotate credentials regularly

  • Change API keys quarterly
  • Use different keys for dev/staging/prod
  • Keep audit logs of key changes

Database Setup (Supabase)

Your Supabase database should already be configured from the Environment Variables guide.

Production Database Configuration

1

Enable connection pooling

In Supabase Dashboard → Database Settings:
  • Enable connection pooling
  • Set max connections based on your plan
2

Configure Row Level Security

Review and update RLS policies for production:
-- Restrict access to authenticated users only
CREATE POLICY "Authenticated users can read calls" ON calls
  FOR SELECT USING (auth.role() = 'authenticated');

CREATE POLICY "Authenticated users can insert calls" ON calls
  FOR INSERT WITH CHECK (auth.role() = 'authenticated');
3

Set up backups

  • Enable automatic daily backups in Supabase
  • Configure Point-in-Time Recovery (PITR) if available
  • Test restore process periodically
4

Monitor database performance

  • Review query performance in Supabase dashboard
  • Add indexes for frequently queried columns
  • Monitor database size and plan accordingly

Domain and SSL Setup

Custom Domain Configuration

1

Backend domain

  1. Add A record pointing to your backend server IP
  2. Or add CNAME to your platform’s domain
  3. Example: api.your-domain.com
2

Frontend domain

  1. Add A record or CNAME for frontend
  2. Example: app.your-domain.com or www.your-domain.com
3

Update environment variables

Update NEXT_PUBLIC_BACKEND_URL to use your custom domain:
NEXT_PUBLIC_BACKEND_URL=https://api.your-domain.com

SSL Certificate Setup

Most platforms (Vercel, Railway, Render) provide automatic SSL. For self-hosted deployments:
# Install Certbot
sudo apt-get install certbot python3-certbot-nginx

# Get certificates
sudo certbot --nginx -d api.your-domain.com -d app.your-domain.com

# Auto-renew
sudo certbot renew --dry-run
SSL is required for productionTwilio media streams require WSS (WebSocket Secure), which requires HTTPS/SSL certificates.

CORS Configuration for Production

Update backend CORS settings to only allow your frontend domain:
index.js
app.use(
  cors({
    origin: "https://app.your-domain.com", // Your frontend domain
    methods: ["GET", "POST", "PUT", "DELETE"],
    credentials: true,
  })
);
For multiple domains:
const allowedOrigins = [
  "https://app.your-domain.com",
  "https://www.your-domain.com",
];

app.use(
  cors({
    origin: (origin, callback) => {
      if (!origin || allowedOrigins.includes(origin)) {
        callback(null, true);
      } else {
        callback(new Error("Not allowed by CORS"));
      }
    },
    credentials: true,
  })
);

Health Checks and Monitoring

Backend Health Check

The backend provides a health check endpoint:
curl https://api.your-domain.com/
Expected response:
{"message":"Running"}

Monitoring Setup

1

Set up uptime monitoring

Use services like:Monitor both backend and frontend URLs.
2

Configure logging

  • Backend: Winston logs to console (captured by platform)
  • Frontend: Next.js logs
  • Consider external logging: Datadog, LogRocket, Sentry
3

Set up error tracking

Install Sentry for error monitoring:
npm install @sentry/node @sentry/nextjs
Configure in both backend and frontend.

Deployment Checklist

Before going live:
  • Backend deployed with all environment variables
  • Frontend deployed with Supabase configuration
  • Database migrations applied
  • RLS policies configured
  • Custom domains configured
  • SSL certificates active
  • CORS configured for production domain
  • Health checks responding
  • Twilio webhook URLs updated
  • OpenAI API limits reviewed
  • Monitoring and alerts configured
  • Backup strategy in place
  • Documentation updated with production URLs

Post-Deployment

1

Test full call flow

  1. Trigger a call from the frontend
  2. Verify Twilio connects successfully
  3. Test OpenAI conversation
  4. Confirm call logs appear in database
2

Monitor initial traffic

  • Watch server logs for errors
  • Monitor API rate limits
  • Check database connection pool
  • Review error rates
3

Optimize performance

  • Enable CDN for frontend assets
  • Configure database indexes
  • Implement caching where appropriate
  • Review and optimize API calls

Troubleshooting

Build failures?
  • Check Node.js version matches locally
  • Verify all dependencies in package.json
  • Review build logs for specific errors
WebSocket connection issues?
  • Ensure platform supports WebSockets
  • Verify SSL certificates are valid
  • Check CORS configuration
  • Test with WSS protocol (not WS)
Environment variables not working?
  • Redeploy after adding new variables
  • Check variable names match exactly
  • Verify frontend variables have NEXT_PUBLIC_ prefix
Database connection errors?
  • Verify Supabase URL and key
  • Check RLS policies aren’t blocking access
  • Review connection pool settings
  • Test database connection in Supabase dashboard

Next Steps

API Reference

Explore Highway API endpoints

Voice Configuration

Customize voice assistant behavior

Build docs developers (and LLMs) love