Getting started
This section walks an operator through bringing up a brand-new Delphi deployment. The end goal is a stack that answers calls and serves the dashboard. Each service has its own operations page that documents service-specific knobs once you have a deployment running.
What "a deployment" is
A Delphi deployment is:
- A set of container images (
voiceai-telapi,voiceai-telweb,voiceai-telphi,voiceai-telsys,voiceai-telpro,voiceai-media-server,voiceai-scaler,voiceai-tasker, plus a few upstream images) pinned to a release tag. - A set of per-service config bundles (each contains a
docker-compose.yaml, aninit.sh, avars.yaml, and any extra service-specific files). The bundles live in an S3 bucket that every host fetches from at boot. - A set of runtime variables in AWS SSM Parameter Store (non-sensitive) and AWS Secrets Manager (sensitive), grouped under a
NAMESPACElikevoiceai/stagingordelphi/prod. - A set of cloud instances (one per service role) wired together by a private network. Each instance runs a thin cloud-init that places
/opt/deployment/.envand/opt/services/<role>/, then runsinit.sh.
Everything below is about producing those four things.
The six steps
- Prerequisites — accounts, DNS, the S3 config bucket, the container image registry, the namespace.
- Configure environment — feed every service's
vars.yamlinto SSM and Secrets Manager sofetch-env.shcan resolve them at boot. - Provision instances — provider-neutral host requirements: cloud-init, private networking, Docker, IAM, volumes, and load balancers.
- Bootstrap and init — what
init.shdoes on first run: pull config from S3, fetch env from SSM/SM into memory, decode TLS material, pull images,docker compose up. - Verify — follow the smoke checks at the end of Bootstrap and init (every host, dashboard, API through the load balancer).
- First use ·
delphi-setup— on the Ops host, afterinit.shhas rundb-migrate, run./delphi-setup.shfor registry steps (platform superuser, etc.). Optional:delphi-setupCLI reference for every flag.
Steps 1–5 give you containers that pass health checks and a dashboard that loads; step 6 is what makes the first administrator account and other first-use registry rows land in Postgres. For upgrades, re-run ./delphi-setup.sh --apply-missing when the release notes say so.
From there, day-2 operations live in the per-service operations pages.
Same shape, different specifics per service
The init.sh path is the same for every service role — that is the whole point of the vars.yaml + fetch-env.sh + init.sh pattern. Ops init.sh runs schema migrations automatically; delphi-setup registry steps are the separate step 6 via ./delphi-setup.sh on the Ops host. Each service's init.sh adds its own specifics on top:
| Service | Per-service specifics on top of the common flow |
|---|---|
| Database | Mounts the data volume; runs prepare-tls-server.sh; creates the OTel monitoring user on first boot. |
| Media | Resolves TLS material in three branches (env-PEM → existing files → self-signed) and writes a CA-for-clients PEM that consumers trust. |
| TelPro | Resolves TLS via Certbot, Secrets Manager, or self-signed; maps LOG_LEVEL to Kamailio/RTPEngine numeric levels. |
| Voice | Copies the log-to-span binary into TelSys; brings up Asterisk + TelPhi + optional AudioProc. |
| API | Decodes the TTS-cache CA bundle into memory; auto-detects PRIVATE_IP from a 10.x interface. |
| Web | TelWeb entrypoint waits for Postgres, then starts Next.js. Caddy auto-issues Let's Encrypt for DOMAIN_TELWEB. |
| SigNoz | Clones the upstream SigNoz repo; converts named volumes to bind mounts; configures redsocks-based transparent proxy via Squid. |
| Squid | Brings up first; no app variables — squid.conf is the configuration surface. |
| Ops | Runs db-migrate during init.sh; operators run ./delphi-setup.sh for first-use and upgrade registry steps. Email transport (SMTP or SES); Scaler/Tasker leader election. See First use. |
Recommended deploy order
Foundation services come up first because everything else depends on them:
- Squid — every private VM needs an egress proxy.
- SigNoz — fixed private IP
10.0.1.10so every other OTel collector can target it. - Database — Postgres + Redis.
- Media — private TLS material has to land in SSM/SM before consumers reference it.
- TelPro — public IP and DNS need to settle for Janus WSS.
- Ops (migrations) — run
init.sh(or at minimum thedb-migrateone-shot) so schema and baseline seed land before application services expect a ready database. - Web — public IP and DNS need to settle for Let's Encrypt; TelWeb waits for Postgres, then starts Next.js.
- API — registers behind the managed load balancer.
- Voice — joins the Kamailio dispatcher set in Redis as it boots.
- First use — after the dashboard loads, run
./delphi-setup.shon the Ops host for the platform superuser and other registry steps. - Bastion — last, since it knows every other instance's private IP.
Within each service you can re-run init.sh (or update.sh --restart-only) any time after a SSM/SM change.
Next
Continue to Prerequisites.