Skip to content

Deployment

Overview

Faxbot runs as a small set of services: the API (required), optional MCP servers (Node/Python), and an optional SIP/Asterisk backend when you choose the self‑hosted path. This guide covers production‑grade settings, TLS, reverse proxy, storage, and hardening.

Deployment Checklist

  • Select backend: phaxio/sinch (cloud) or sip (self‑hosted).
  • Set a strong API_KEY and enable REQUIRE_API_KEY=true.
  • Pick a database: leave SQLite for dev; use Postgres in prod (DATABASE_URL).
  • Configure storage: local (dev) or S3/S3‑compatible for artifacts.
  • Expose a public HTTPS URL (PUBLIC_API_URL), put a reverse proxy in front.
  • Enable ENFORCE_PUBLIC_HTTPS=true for cloud backends.
  • Run with Docker Compose; add a process supervisor or systemd unit.
  • Lock down ports (no public AMI), set firewall/NAT according to backend.
  • Turn on artifact cleanup (ARTIFACT_TTL_DAYS).
  • Configure provider webhooks (cloud) or Asterisk dialplan (SIP).

Services & Ports

  • api — FastAPI service (required) · port 8080
  • faxbot-mcp — Node MCP (optional) · ports 3001 (HTTP), 3002 (SSE)
  • faxbot-mcp-py — Python MCP (optional) · port 3003 (SSE)
  • asterisk — SIP/Asterisk (SIP only) · ports 5060 (SIP), 4000–4999 (UDPTL), 5038 (AMI, internal only)

Environment (minimal)

# Core
API_KEY=change_me_strong
REQUIRE_API_KEY=true
PUBLIC_API_URL=https://fax.example.com

# Backend (choose one)
FAX_BACKEND=phaxio
PHAXIO_API_KEY=...
PHAXIO_API_SECRET=...

# Database (prod)
DATABASE_URL=postgresql+psycopg://user:pass@db:5432/faxbot

# Storage (optional prod)
STORAGE_BACKEND=s3
S3_BUCKET=faxbot-artifacts
S3_ENDPOINT=https://s3.amazonaws.com
S3_REGION=us-east-1
S3_ACCESS_KEY=...
S3_SECRET_KEY=...

Docker Compose

# Build and start API (and Admin Console)
docker compose up -d --build api

# Optional MCP
docker compose --profile mcp up -d --build faxbot-mcp
docker compose --profile mcp up -d --build faxbot-mcp-sse

Reverse Proxy & TLS

Nginx

server {
  listen 443 ssl http2;
  server_name fax.example.com;

  ssl_certificate     /etc/ssl/fullchain.pem;
  ssl_certificate_key /etc/ssl/privkey.pem;
  add_header Strict-Transport-Security "max-age=31536000" always;

  client_max_body_size 12m; # API accepts up to 10 MB

  location / {
    proxy_pass http://api:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Caddy

fax.example.com {
  encode zstd gzip
  header Strict-Transport-Security "max-age=31536000"
  reverse_proxy api:8080
}

Do not expose AMI or UDPTL

Port 5038 (AMI) and UDPTL ports must not be internet‑exposed. Restrict them to your private network.

Storage & Database

  • Artifacts: FAX_DATA_DIR for PDFs/TIFFs (default ./faxdata). Enable cleanup with ARTIFACT_TTL_DAYS.
  • Database: use Postgres in production via DATABASE_URL. Back up regularly.
  • S3/S3‑compatible: recommend SSE‑KMS for PHI. See AWS KMS.

Security

Production posture

  • REQUIRE_API_KEY=true and send X-API-Key on every request.
  • ENFORCE_PUBLIC_HTTPS=true when using cloud backends that fetch PDFs and post callbacks.
  • Rotate/revoke admin keys via POST /admin/api-keys/DELETE /admin/api-keys/{id}.

Observability

  • Health: /health and /health/ready
  • Metrics: /metrics (Prometheus format)
  • Logs: avoid PHI; only IDs/metadata are logged.
  • Rate limiting: MAX_REQUESTS_PER_MINUTE (optional)

Provider Setup

  • Phaxio: configure callback URL at PUBLIC_API_URL/phaxio-callback.
  • Sinch: register webhooks per provider limits; see Sinch setup.
  • SIP/Asterisk: post inbound events to /_internal/asterisk/inbound (private), secured by X-Internal-Secret.

Dev Tunnels (non‑PHI)

  • Cloudflare: Quick Tunnel
  • ngrok (HTTP): guide
  • For HIPAA, prefer a stable HTTPS domain or named tunnels with Access policies.

Appendix