Library
Voice AI · Chapter 8 of 10
Chapter 08

Deploying Voice AI
Applications

Railway, Render, Docker, AWS, Cloudflare, Vercel — plus logging, secrets, security, rate limits, scaling and CI/CD.

DeployDockerAWSCI/CDSecurity
A Handbook For Builders
Deploying Voice AI
Applications
Chapter 08
The Claude Code Handbook

Shipping a voice agent is 40% code and 60% operations. This chapter is the operations half — six platforms, one Dockerfile, one CI pipeline, and a production checklist you can print and pin above your monitor.

Section 1

1. Railway — Fastest Path

  1. Push repo to GitHub.
  2. Railway → New Project → Deploy from GitHub → pick repo.
  3. Variables tab → paste all keys from .env.
  4. Set start command node dist/index.js. Deploy.
Claude Code — Terminal
Screenshot placeholder
Railway dashboard with a green Active deployment and a public URL.
Figure — Railway dashboard with a green Active deployment and a public URL.
Section 2

2. Render — Almost Identical

Same flow, slightly cheaper for always-on workers. Good WebSocket support.

Section 3

3. Docker — the Universal Package

dockerfileclaude-code
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build
EXPOSE 3000
HEALTHCHECK CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
bashclaude-code
docker build -t voice-agent .
docker run -p 3000:3000 --env-file .env voice-agent
Section 4

4. AWS — Production Scale

  • ECS Fargate for stateless containers.
  • ALB in front for TLS + WebSocket routing.
  • RDS Postgres for durable state.
  • Secrets Manager for keys.
Section 5

5. Cloudflare Workers

Edge functions with global latency. Great for the HTTP webhook layer. Cannot hold long-lived Twilio WebSockets — pair with a Durable Object or an origin server.

Section 6

6. Vercel

Perfect for the dashboard front-end. Serverless functions are OK for short jobs; use a dedicated worker (Railway) for long-lived voice sockets.

Section 7

7. Logging

tsclaude-code
import pino from "pino";
export const log = pino({ level: process.env.LOG_LEVEL ?? "info" });
log.info({ call_id, ms_total }, "turn.done");
Section 8

8. Monitoring

  • Uptime — BetterStack pinging /health every 30s.
  • Metrics — Grafana Cloud dashboards (latency p50/p95, cost/call).
  • Errors — Sentry with source maps.
  • Alerts — PagerDuty on p95 > 2s for 5 minutes.
Section 9

9. Secrets Management

  • Never commit .env. Ever.
  • Store secrets in the platform (Railway Variables, AWS SM, Cloudflare Secrets).
  • Rotate every 90 days. Automate rotation for Twilio + ElevenLabs.
Section 10

10. API Keys — Per Environment

Separate keys for dev, staging, prod. Never share across environments.

Section 11

11. Security

  • Verify every webhook signature (Twilio, Stripe, ElevenLabs).
  • Rate limit per IP + per phone number.
  • Strip PII from logs (mask phone middle 4 digits).
  • TLS only. HSTS on the dashboard domain.
Section 12

12. Rate Limits

tsclaude-code
import rateLimit from "express-rate-limit";
app.use("/api", rateLimit({ windowMs: 60_000, max: 60 }));   // 60 req/min/IP
Section 13

13. Scaling

  • Autoscale on CPU or on active WebSocket count.
  • Sticky sessions for calls (or hand off state via Redis on reconnect).
  • Warm pool of 2 instances always up to avoid cold-start on first ring.
Section 14

14. CI/CD

  1. PR opens → run test, lint, typecheck.
  2. Merge to main → build Docker image → push to registry.
  3. Deploy to staging automatically. Prod behind a manual approval.
  4. Smoke test after deploy: place one synthetic call, assert audio returned.
Section 15

15. GitHub Actions — Complete Pipeline

yamlclaude-code
name: deploy
on: { push: { branches: [main] } }
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npm ci
      - run: npm test
      - run: npm run build
Section 16

16. Production Checklist

  • Health endpoint returning 200.
  • Structured logs shipping to a real log store.
  • Alerts on error rate, p95 latency, cost/day.
  • Secrets in platform vault, not repo.
  • Webhook signature verification.
  • Rate limits at the edge and app layer.
  • Docker image reproducible from any commit.
  • Rollback tested — one command back to last green build.
  • Synthetic call in CI on every deploy.