Fly.io Deployment
The Voice Server is deployed on Fly.io for low-latency, global edge deployment.
Why Fly.io?
- Edge locations: Deploy close to OpenAI's servers (US East)
- WebSocket support: Native support for long-running connections
- Auto-scaling: Scale based on concurrent connections
- Zero-downtime deploys: Rolling updates without interruption
Configuration
fly.toml
app = "justcall-voice-server"
primary_region = "iad" # Ashburn, Virginia - closest to OpenAI
[build]
dockerfile = "Dockerfile"
[env]
NODE_ENV = "production"
PORT = "8080"
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = false
auto_start_machines = true
min_machines_running = 1
[[services]]
internal_port = 8080
protocol = "tcp"
[[services.ports]]
port = 443
handlers = ["tls", "http"]
[[services.ports]]
port = 80
handlers = ["http"]
[[vm]]
cpu_kind = "performance"
cpus = 2
memory_mb = 1024
Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist ./dist
ENV NODE_ENV=production
ENV PORT=8080
EXPOSE 8080
CMD ["node", "dist/index-unified.js"]
Deployment Steps
1. Install Fly CLI
# macOS
brew install flyctl
# Or via script
curl -L https://fly.io/install.sh | sh
2. Login
flyctl auth login
3. Create App (First Time)
cd voice-server
flyctl launch --name justcall-voice-server --region iad --no-deploy
4. Set Secrets
flyctl secrets set \
SUPABASE_URL="https://xxx.supabase.co" \
SUPABASE_SERVICE_ROLE_KEY="eyJ..." \
OPENAI_API_KEY="sk-proj-..." \
REDIS_URL="rediss://..." \
ADMIN_TOKEN="secure-token"
5. Deploy
# Build and deploy
npm run build
flyctl deploy
Scaling
Horizontal Scaling
# Scale to 3 machines
flyctl scale count 3
# Check current scale
flyctl scale show
Vertical Scaling
# Upgrade machine size
flyctl scale vm performance-2x
flyctl scale memory 2048
Auto-Scaling
# In fly.toml
[http_service]
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 1
max_machines_running = 10
Monitoring
Logs
# Stream logs
flyctl logs
# Filter by app
flyctl logs -a justcall-voice-server
Metrics
# View metrics dashboard
flyctl dashboard
Health Checks
# In fly.toml
[[services.http_checks]]
interval = "10s"
timeout = "2s"
grace_period = "5s"
method = "GET"
path = "/health"
Regions
Primary region is iad (Ashburn) for OpenAI proximity:
| Region | Code | Latency to OpenAI |
|---|---|---|
| Ashburn, VA | iad | ~5ms |
| Frankfurt | fra | ~100ms |
| Singapore | sin | ~200ms |
# Deploy to additional regions
flyctl regions add fra sin
# Check regions
flyctl regions list
Secrets Management
# List secrets
flyctl secrets list
# Update secret
flyctl secrets set OPENAI_API_KEY="sk-new-key"
# Remove secret
flyctl secrets unset OLD_SECRET
Troubleshooting
Connection Issues
# SSH into machine
flyctl ssh console
# Check process
ps aux | grep node
# View environment
env | grep SUPABASE
Deployment Failures
# View build logs
flyctl logs --instance <instance-id>
# Rollback
flyctl releases list
flyctl deploy --image <previous-image>
Memory Issues
# Check memory usage
flyctl status
# Increase memory
flyctl scale memory 2048
CI/CD Integration
GitHub Actions
# .github/workflows/deploy-voice-server.yml
name: Deploy Voice Server
on:
push:
branches: [main]
paths:
- 'voice-server/**'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: |
cd voice-server
npm ci
npm run build
flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}