Files
gogo-telefon/docs/DEPLOY.md
Senad Uka fd45ff84dc M6 + M0: hardening, deploy docs, PoC scripts
- Pipeline-down fallback: dialplan plays gogo-fallback after a failed
  AudioSocket (§15) + script to synthesize the Bosnian prompt via TTS
- Voice heartbeat file → /health/voice endpoint + live status in admin panel
- Retention job also purges stale call registrations; chat sessions metered;
  100%-usage super-admin alert email (GOGO_ADMIN_ALERT_EMAIL)
- .env.example, docs/DEPLOY.md (compose stack, GPU node, backups pg_dump,
  update procedure, security notes)
- §16 Definition of Done as an automated test: softphone-style call → fake
  partner availability → request pushed → webhook confirm → console SMS
- M0 PoC scripts: STT accuracy harness (CER/WER + spoken-digit check; dry-run
  verified with espeak-ng samples + faster-whisper small on CPU — phone number
  extracted exactly), TTS bake-off (Azure vs ElevenLabs, latency+cost), and
  end-to-end latency smoke test speaking real AudioSocket to the live pipeline

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:27:05 +02:00

96 lines
3.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Deploy — founder's DC (Docker Compose, §3/§16 M6)
## Layout
| Service | What | Where |
|---|---|---|
| `db` | PostgreSQL 16 | any node |
| `app` | FastAPI backend (dashboard, admin, widget, webhooks, action links) | any node |
| `voice` | AudioSocket server + Whisper STT | **GPU node** |
| `asterisk` | SIP server (softphones, GSM gateway) | host networking, reachable by the gateway |
## First install
```bash
git clone <repo> && cd gogotelefon
cp .env.example .env # fill everything in; strong GOGO_SECRET_KEY!
docker compose build
docker compose up -d db app # app runs alembic upgrade head on start
docker compose --profile voice up -d voice
# Asterisk config comes from the DB:
docker compose exec app python -m gogo.telephony.asterisk --out ./asterisk/conf \
--backend http://app:8000 --voice voice:9092
python scripts/generate_fallback_audio.py ./asterisk/sounds # needs a TTS key
docker compose --profile voice up -d asterisk
# seed the first admin (or python -m gogo.seed for a full demo tenant):
docker compose exec app python - <<'EOF'
import asyncio
from gogo.auth import hash_password
from gogo.db import get_sessionmaker
from gogo.models import Admin
async def main():
async with get_sessionmaker()() as s:
s.add(Admin(email="you@gogotelefon.ba", password_hash=hash_password("CHANGE-ME")))
await s.commit()
asyncio.run(main())
EOF
```
Put a TLS reverse proxy (caddy/nginx) in front of `app:8000` for
`GOGO_BASE_URL` — action links and the widget are public.
## GPU node for Whisper
`Dockerfile.voice` installs CPU wheels by default. On the GPU node use the
NVIDIA runtime and set `GOGO_WHISPER_DEVICE=cuda`, `GOGO_WHISPER_MODEL=large-v3`
(one RTX 4090/L4 handles 1015 concurrent calls, §3). Scale by adding voice
containers and pointing different tenants' Asterisk `GOGO_VOICE` at them.
## Operational jobs (built-in, APScheduler in `app`)
- proposal expiry + owner reminders — every 5 min
- partner polling fallback — every 5 min
- retention: delete call audio older than `GOGO_AUDIO_RETENTION_DAYS`
(transcripts kept, §5.4), purge stale call registrations — daily 04:00
## Monitoring
- `GET /health` (app), `GET /health/db`, `GET /health/voice` (heartbeat age)
- admin panel → *Sistem*: DB, LLM key, email/SMS mode, voice heartbeat,
delivery errors from `sms_log`/`email_log`
- per-call latency breakdown: `calls.trace.turns[].{stt_ms,llm_ms}`
## Backups
```bash
# nightly dump (cron on the DB node) — keep 14 days
docker compose exec -T db pg_dump -U gogo gogo | gzip > /backup/gogo-$(date +%F).sql.gz
find /backup -name 'gogo-*.sql.gz' -mtime +14 -delete
```
Recordings volume: rsync `/data/recordings` if call audio must survive node
loss (transcripts are in the DB either way; audio expires after 90 days).
Restore: `gunzip -c dump.sql.gz | docker compose exec -T db psql -U gogo gogo`.
## Update procedure
```bash
git pull
docker compose build app voice
docker compose up -d app voice # alembic migrates on app start
# if workers/tenants changed the SIP layout:
docker compose exec app python -m gogo.telephony.asterisk --out ./asterisk/conf ...
docker compose exec asterisk asterisk -rx 'core reload'
```
## Security notes
- OAuth tokens + partner API keys are encrypted at rest (Fernet from
`GOGO_SECRET_KEY`) — changing the key orphans them (reconnect/re-enter).
- `/internal/*` must not be exposed publicly (compose keeps it on the
internal network; the reverse proxy should only forward what's needed).
- Action links are signed + single-use; widget is rate-limited per IP.