Self-Hosted Deployments#
CallFluence runs without any external platform dependency on your own infrastructure: two Node services with zero npm dependencies, one SQLite database, one reverse proxy.
Architecture#
| Service | Role | Port | Must be public? |
|---|---|---|---|
console-api | Control plane (assistants, scripts, leads) | 5810 | via reverse proxy |
voice-runtime | Data plane (telephony webhooks, conversations) | 5811 | yes, for carrier webhooks |
Both services share the code tree and the database and run under an unprivileged service account.
Requirements#
- Node.js 22 or newer (uses
node:sqlite— no npm install needed) - Reverse proxy with TLS (e.g. Caddy)
- Writable data directory for the SQLite database (WAL mode)
Start#
bash
# Control plane PORT=5810 DB=/srv/callfluence/data/callfluence.db \ node services/console-api/server.mjs # Data plane PORT=5811 DB=/srv/callfluence/data/callfluence.db \ node services/voice-runtime/server.mjs
systemd (excerpt)#
ini
[Service] User=svc-callfluence ExecStart=/usr/bin/node /srv/callfluence-backend/app/services/console-api/server.mjs Restart=always Environment=PORT=5810 NoNewPrivileges=true ProtectSystem=strict ReadWritePaths=/srv/callfluence-backend/data
Runtime environment#
Secrets live in a 0600 file (default /etc/callfluence/voice-runtime.env), never in code:
| Variable | Purpose |
|---|---|
CARTESIA_API_KEY | Activates the direct Cartesia path (Sonic-3, Ink) |
CARTESIA_VOICE_ID | Optional fixed voice for the direct path |
TOGETHER_ENV | Path to the Together key file (fallback path) |
XAI_API_KEY | Conversation LLM (Grok) |
TENIOS_ACCESS_KEY | Carrier access |
CORS_ORIGINS | Allow list of console origins |
Operating rules#
- Database migrations run idempotently on every start (add columns via
ALTER, indexes afterwards). - The Voice Runtime webhook path contains a secret; the carrier access key can be enforced in addition.
- Before every frontend deploy: compare the live state against the source (checksums) and create a backup.