Web service operations
The Web service hosts the TelWeb management dashboard (Next.js) behind a Caddy reverse proxy with automatic HTTPS. Caddy also reverse-proxies the SigNoz dashboard. Single instance, static IP.
- Overview
- Runbook
- Configuration
- Troubleshooting
Containers
| Container | Image | Port(s) | Purpose |
|---|---|---|---|
voiceai-telweb | ${ECR_REGISTRY}/voiceai-telweb:${ECR_TAG} (Node 24-alpine) | 5050 | Next.js dashboard |
voiceai-caddy | caddy:2-alpine | 80, 443 | Reverse proxy + automatic Let's Encrypt TLS |
voiceai-otel-collector | otel/opentelemetry-collector-contrib:0.150.1 | — | Telemetry collector (host network) |
TelWeb and Caddy share a bridge network (web). The OTel collector runs in host network mode and TelWeb reaches it via host.docker.internal.
Caddyfile
The Caddyfile configures two virtual hosts:
${DOMAIN_TELWEB}— reverse-proxy totelweb:5050; HSTS, X-Frame-Options, gzip, static asset caching.${DOMAIN_SIGNOZ}— reverse-proxy to${OTEL_BACKEND_HOST}:${SIGNOZ_PORT}(default10.0.1.10:8080).
Migrations and baseline seed
TelWeb entrypoint.sh waits until Postgres accepts TCP connections (when DATABASE_URL is set), then runs prisma generate, prisma migrate deploy, and the baseline prisma db seed before starting Next.js. The container has a 40-second start period so first boot has time for migrations plus seed — subsequent boots are faster.
The delphi-setup CLI is not invoked by entrypoint.sh. Operators run docker compose exec -it voiceai-telweb delphi-setup for interactive first-use registry steps (superuser, etc.), --apply-missing after releases, and --dev-seeds when needed — see First use on TelWeb and delphi-setup CLI.
TelWeb entrypoint only applies migrations and baseline seed. Confirm logs show ✅ Baseline seed completed, then run delphi-setup onboard and after upgrades (--apply-missing).
Deploy and update
init.sh reads the bootstrap /opt/deployment/.env, fetches config from S3, loads SSM / Secrets Manager values into memory via fetch-env.sh, logs into ECR, and starts Compose.
cd /opt/services/web
./init.sh # full bring-up
./update.sh --ecr-tag v0.9.11 # roll a new image
./update.sh --restart-only # restart without pulling new images
Both init.sh and update.sh accept --skip-images, --skip-fetch, --dry-run.
TLS
Caddy obtains and renews Let's Encrypt certificates automatically for DOMAIN_TELWEB and DOMAIN_SIGNOZ. Certificates persist in the caddy-data named volume. No manual cert rotation is needed; verify DNS resolves to the static IP before relying on auto-issuance.
Health checks
| Container | Probe | Interval | Notes |
|---|---|---|---|
voiceai-telweb | wget --spider http://127.0.0.1:5050/ | 30s | 40s start period for migrations |
voiceai-caddy | wget --spider http://127.0.0.1:2019/config/ | 30s | Caddy admin endpoint |
TelWeb (Next.js)
| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
DATABASE_URL | Secrets Manager | all | — | PostgreSQL connection string. |
DATABASE_SSL_MODE | SSM | all | disable | disable | require | verify-ca | verify-full. |
REDIS_HOST | SSM | all | — | Redis server address. |
REDIS_PASSWORD | Secrets Manager | all | — | Redis authentication. |
REDIS_TLS_ENABLED | SSM | all | false | Enable TLS for Redis client connections. |
NEXTAUTH_URL | SSM | all | — | Base URL used by NextAuth. |
NEXTAUTH_SECRET | Secrets Manager | all | — | Session encryption key. Must match across all consumers. |
AUTH_WITH_MICROSOFT | SSM | all | false | Enable Entra ID auth (requires the trio of MICROSOFT_ENTRA_ID_* vars). |
STRIPE_SECRET_KEY | Secrets Manager | all | — | Subscription billing. |
STRIPE_WEBHOOK_SECRET | Secrets Manager | all | — | Stripe webhook signature verification. |
DELPHI_PLATFORM_ROLE_ARN | SSM | all | — | AWS IAM role for Delphi platform features (replaces password-based setup). |
TELAPI_KEY | Secrets Manager | all | — | TelAPI key for the WebRTC phone component. |
ICE_SERVERS | SSM | all | — | Optional full ICE JSON override (otherwise derived from telproDomain in the session-token response). |
Caddy
| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
DOMAIN_TELWEB | SSM | all | — | Primary dashboard domain. |
DOMAIN_SIGNOZ | SSM | all | — | Monitoring dashboard domain. |
OTEL_BACKEND_HOST | SSM | all | 10.0.1.10 | SigNoz host IP (proxy target). |
SIGNOZ_PORT | SSM | all | 8080 | SigNoz UI port. |
See Configuration model for how SSM / Secrets Manager / DB sources fit together.
| Symptom | Likely cause | Check |
|---|---|---|
| HTTPS broken / cert errors | Caddy ACME failure | docker compose logs voiceai-caddy; verify DNS for DOMAIN_TELWEB. |
| 502 Bad Gateway | TelWeb crash on boot | docker compose ps voiceai-telweb; tail TelWeb logs. |
| Slow first page load | First-boot migrations | Wait out the 40s start period; subsequent boots are fast. |
| Auth fails everywhere | NEXTAUTH_SECRET drift between API and TelWeb | Ensure both services pull the same value from Secrets Manager. |
| SigNoz dashboard 502 | Caddy cannot reach 10.0.1.10:8080 | curl http://10.0.1.10:8080 from the Web instance; check SigNoz health. |
| Email notifications not sending | Email is sent from the Ops (Tasker) service, not TelWeb | Check Tasker logs on the Ops instance for SMTP / SES errors. |
See also
- API operations — the LB-backed Fastify API TelWeb talks to.
- Configuration model — where each variable lives and how to change it.
- Monitoring in SigNoz — finding TelWeb traces, logs, dashboards, and alerts.