TelPro service operations
The TelPro service is the public-facing telephony gateway. It runs Kamailio (SIP proxy), RTPEngine (media proxy), Janus (WebRTC gateway), and coturn (TURN server). Inbound SIP calls and WebRTC sessions arrive here and route to Voice instances for AI processing. Single instance, static IP.
- Overview
- Runbook
- Configuration
- Troubleshooting
Containers
| Container | Base | Port(s) | Purpose |
|---|---|---|---|
voiceai-telpro | Kamailio 6.1.1-bookworm (ghcr.io/kamailio/kamailio) | 5060 UDP/TCP · 5061 TLS | SIP signaling |
voiceai-rtpengine | RTPEngine 14.1 (dfx.at channel) | 22222/UDP ng · 20000–40000/UDP RTP | Media proxy |
voiceai-webrtc | Janus v1.3.3 (built from source) | JANUS_WS_PORT (default 443) WSS · 10000–12000/UDP RTP | WebRTC gateway |
voiceai-turn | coturn/coturn:4.6.2 | 3478 / 5349 · 49152–51152/UDP relay | TURN server |
log-to-span | alpine:3.19 + Go binary | — | Structured-log → OTLP spans for Kamailio / RTPEngine / Janus |
voiceai-otel-collector | otel/opentelemetry-collector-contrib:0.150.1 | — | Telemetry collector |
The Kamailio, Janus, and RTPEngine versions are pinned in the image source under .docker/voiceai-{telpro,webrtc,rtpengine}/Dockerfile; coturn and the OTel collector are pinned in .infrastructure/services/telpro/docker-compose.yml. See Version sources.
WebRTC image notes
voiceai-webrtc is the Janus Gateway container that ships with the TelPro service when the webrtc flag is on:
- Image — pulled from ECR as
${ECR_REGISTRY}/voiceai-webrtc:${ECR_TAG}like the rest of the Delphi images. - Runtime — Janus v1.3.3 built from source with the SIP plugin enabled.
- TLS material — mounts
/opt/services/telpro/tls/server.{crt,key}, shared with Kamailio. - Signaling path — exposes WSS on
JANUS_WS_PORTand connects outbound to Kamailio through the Janus SIP plugin.
Firewall
The most permissive of any service: TCP 22/80/443/5060/5061/3478/5349, UDP 5060/3478/5349, and UDP ranges 10000–12000, 20000–40000, 49152–51152.
TLS certificates
Three sources in priority order:
- Certbot (Let's Encrypt) — when
DOMAIN_TELPROis set andCERTBOT_ENABLED=true. Requires port 80 open for HTTP-01. - SSM / Secrets Manager — base64-encoded
TLS_SERVER_CRT,TLS_SERVER_KEY,TLS_CA_CRT. Generated viacat server.crt | base64 | tr -d '\n'. - Manual files — drop into
/opt/services/telpro/tls/; ensurechmod 600 server.key.
Self-signed certificates are generated automatically when TLS is enabled but no material is provided. Do not rely on self-signed in production.
Log level mapping
init.sh maps a human-readable LOG_LEVEL to the numeric values Kamailio and RTPEngine expect:
LOG_LEVEL | RTP_LOG_LEVEL | DEBUG_LEVEL |
|---|---|---|
error | 1 | 0 |
warn | 2 | 1 |
info | 4 | 2 |
debug | 7 | 3 |
Change with LOG_LEVEL in SSM, then ./update.sh --restart-only.
Deploy and update
cd /opt/services/telpro
./init.sh
./update.sh --ecr-tag v0.9.11
./update.sh --restart-only
Kamailio Redis keys
Kamailio stores routing state in Redis (on the Database instance):
docker exec -it voiceai-redis redis-cli -a "${REDIS_PASSWORD}"
KEYS *dialog* # SIP dialog state
KEYS *dispatcher* # Voice instance routing
KEYS *location* # registrations
GET voiceai:egress:<num> # egress trunk config for a base number
SMEMBERS voiceai:telsys:server_ips
LRANGE voiceai:egress:registrations 0 -1
Kamailio
| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
PUBLIC_IP | SSM | all | — | Public IP for SIP contact headers. |
PRIVATE_IP | SSM | all | — | Private network IP. |
SIP_PORT | SSM | all | 5060 | SIP non-TLS port. |
SIPS_PORT | SSM | all | 5061 | SIP TLS port. |
TLS_ENABLED | SSM | all | false | Enable TLS on SIPS. |
REDIS_HOST | SSM | all | — | Redis address. |
REDIS_PASSWORD | Secrets Manager | all | — | Redis auth. |
REDIS_TLS_ENABLED | SSM | all | false | Requires a voiceai-telpro image built with hiredis_ssl. |
DEBUG_LEVEL | SSM | all | 2 | Mapped from LOG_LEVEL by init.sh. |
Janus (WebRTC gateway)
JANUS_WS_PORTSSMproddefault: 443| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
JANUS_WSS_ENABLED | SSM | all | true | Enable TLS on the WebSocket. |
JANUS_ADMIN_PORT | SSM | all | 7088 | Janus admin API port, bound for local/container administration only. |
JANUS_RTP_PORT_MIN | SSM | all | 10000 | Janus RTP start. |
JANUS_RTP_PORT_MAX | SSM | all | 12000 | Janus RTP end. |
KAMAILIO_SIP_HOST | SSM | all | ${PRIVATE_IP} | Kamailio host Janus dials via the SIP plugin. |
STUN_SERVER | SSM | all | stun.l.google.com | STUN host for ICE. |
STUN_PORT | SSM | all | 19302 | STUN port for ICE. |
TURN_SERVER | SSM | all | — | TURN server address (defaults to PUBLIC_IP). |
TURN_USER | SSM | all | telpro | TURN static user. |
TURN_PASSWORD | Secrets Manager | all | — | TURN static password. |
JANUS_LOG_LEVEL | SSM | all | 4 | Janus log verbosity. |
RTPEngine
| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
RTP_PORT_MIN | SSM | all | 20000 | RTP start. |
RTP_PORT_MAX | SSM | all | 40000 | RTP end. |
RTPENGINE_INTERFACES | SSM | all | — | priv/PRIVATE_IP;pub/PUBLIC_IP (derived from above if unset). |
TURN
| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
TURN_REALM | SSM | all | telpro | TURN realm. |
TURN_PORT | SSM | all | 3478 | TURN standard port. |
TURN_TLS_PORT | SSM | all | 5349 | TURN TLS port. |
TURN_MIN_PORT | SSM | all | 49152 | Relay port start. |
TURN_MAX_PORT | SSM | all | 51152 | Relay port end. |
If you operate your own Janus deployment, set JANUS_WS_PORT (default 8188 locally, 443 in production) so TelWeb dials the correct WebSocket port.
SIP calls
| Symptom | Likely cause | Check |
|---|---|---|
| No incoming calls | Kamailio down or firewall blocking SIP | docker compose ps voiceai-telpro; verify :5060/:5061 reachable from carrier. |
| Calls connect, no audio | RTPEngine down or RTP UDP blocked | docker compose ps voiceai-rtpengine; verify 20000–40000/UDP. |
| One-way audio | NAT / IP misconfiguration | Verify PUBLIC_IP, PRIVATE_IP, and RTPENGINE_INTERFACES. |
| Calls not reaching Voice | Kamailio dispatcher empty | SMEMBERS voiceai:telsys:server_ips in Redis; check Voice instance heartbeats. |
WebRTC
| Symptom | Likely cause | Check |
|---|---|---|
| WebRTC won't connect | Janus down or TLS cert invalid | wss://${DOMAIN_TELPRO}:${JANUS_WS_PORT} reachability. |
| ICE fails | TURN not running or ports blocked | docker compose ps voiceai-turn; verify 3478/5349/UDP and 49152–51152/UDP. |
| WebRTC connects, no audio | Janus → Kamailio SIP bridge broken | Janus logs for SIP register failures; verify KAMAILIO_SIP_HOST. |
Outbound (transfer) calls
| Symptom | Likely cause | Check |
|---|---|---|
| Transfer not routing | Egress trunk not linked to base number | GET voiceai:egress:<num> in Redis should return JSON. |
| 403 from Kamailio | TelSys source IP not in allowlist | SMEMBERS voiceai:telsys:server_ips should include Voice instance IP. |
| Custom headers stripped | Header not in outbound allowlist | GET voiceai:config:outbound_header_allowlist. |
See also
- Voice operations — SIP downstream consumer.
- Database operations — Kamailio Redis state.