Production setup
The quickstart is small on purpose: it creates a test PostgreSQL Deployment, two demo users, one internal dial policy, and two routes. In production, keep the same resource model, but replace the demo pieces with durable infrastructure and real credentials.
Use production PostgreSQL
KubeVoIP expects a PostgreSQL connection Secret with host, port, dbname,
user, and password keys. The database can come from a cloud provider,
CNPG, another PostgreSQL operator, or your own managed service.
Create the Secret without putting the password in shell history:
printf '%s' "$POSTGRES_PASSWORD" | uvx kubevoip -n telephony secret database postgres-app \
--host "$POSTGRES_HOST" \
--port 5432 \
--db kubevoip \
--user kubevoip \
--password-stdinThen create the gateway against that Secret, or initialize the platform with that database:
printf '%s' "$POSTGRES_PASSWORD" | uvx kubevoip -n telephony init \
--database existing \
--postgres-host "$POSTGRES_HOST" \
--postgres-db kubevoip \
--postgres-user kubevoip \
--postgres-password-stdinPostgreSQL stores runtime routing data and HA1 password hashes. Treat HA1 as credential-equivalent material and protect database backups accordingly.
Create SIP device credentials
Each phone should have its own SIPUser and password Secret:
export SIP_PASSWORD="$(openssl rand -base64 32)"
printf '%s' "$SIP_PASSWORD" | uvx kubevoip -n telephony secret sip-user alice-sip \
--from-stdin
uvx kubevoip -n telephony user create alice \
--extension 100 \
--gateway main \
--dial-policy internal-only \
--auth-username alice \
--caller-id "Alice <100>" \
--password-secret alice-sipConfigure the SIP client with:
| Field | Value |
|---|---|
| Server / registrar | The main-sip-gateway external address |
| Username | alice |
| Authentication username | alice |
| Password | The generated Secret value |
| Extension | 100 |
Do not commit raw SIP passwords to Git. If you use GitOps, store credentials through your normal secret-management system and create Kubernetes Secrets from there.
Model who can call what
Use CallScope, DialPolicy, and CallRoute to express the dial plan:
uvx kubevoip -n telephony scope create internal --gateway main
uvx kubevoip -n telephony policy create internal-only \
--gateway main \
--scope internal
uvx kubevoip -n telephony route create bob-extension \
--gateway main \
--scope internal \
--priority 10 \
--match 101 \
--target-user bobA caller can only search scopes listed in its DialPolicy. Put outbound trunks
or application routes in separate scopes when only some callers should use
them.
Expose SIP and RTP deliberately
Before accepting real traffic, read SIP on Kubernetes and LoadBalancer networking. Public SIP and RTP forwarding must preserve ports. KubeVoIP does not configure provider portals, DNS, routers, cloud firewall rules, or perimeter firewalls.
Production checklist
- Use a durable PostgreSQL database and backups.
- Protect PostgreSQL because it stores credential-equivalent HA1 values.
- Use unique SIP credentials per device.
- Keep Secrets out of ConfigMaps and Git.
- Confirm
SIPGateway,MediaRelay,SIPUser,CallScope,DialPolicy, andCallRouteresources report Ready. - Confirm LoadBalancer addresses and firewall rules before testing real calls.
- Document which dial policies are allowed to reach trunks.