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 Web host, after TelWeb's entrypoint finishes Prisma migrate and baselinedb seed, rundocker compose exec -it voiceai-telweb delphi-setupfor 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 --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. delphi-setup is not part of init.sh; it is the separate step 6 on the Web 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: Prisma migrate deploy + baseline prisma db seed, then Next.js. delphi-setup is run by the operator after boot — see First use. 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 | Selects email transport (SMTP or SES via instance profile); leader-elects against Redis. |
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.
- Web — public IP and DNS need to settle for Let's Encrypt; entrypoint runs migrations + baseline seed, then run
delphi-setupfrom the host. - API — registers behind the managed load balancer.
- Voice — joins the Kamailio dispatcher set in Redis as it boots.
- Ops — Scaler and Tasker leader-elect against Redis.
- 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.