npx @egma/cli self-host up command starts the entire stack — API, web application, simulator, grader, databases, object store, and media server — on your own machine or server. This guide walks you through the prerequisites, required secrets, provider configuration, and day-two operations so you can run a production-ready instance without surprises.
Prerequisites
Before you start, make sure you have:- Node 22 or newer — the Egma CLI requires it
- Docker with Compose — the only runtime dependency for the platform itself
- A clone of the Egma repository, or a dedicated workspace directory where you will store platform credentials and configuration
The platform workspace (where you run
self-host up) is deliberately separate from your agent repository. Platform credentials belong to whoever operates the platform; an agent repository holds only tests and the address of the platform it points at. On one laptop both are often yours, and they are still two directories — one platform serves many agent repositories.Step 1 — Copy and fill in the environment file
Clone the Egma repository, then copy the example environment file:.env in an editor. Most values have working defaults and you can leave them alone. Ten variables have no default and the platform refuses to start without them. They are marked REQUIRED in .env.example. The sections below explain each one and how to generate it.
Step 2 — Set the required secrets
Seven of the ten required values are secrets you generate yourself. The remaining three — the LiveKit API key and secret, andEGMA_BASE_URL — are set automatically when you run self-host up.
EGMA_ENCRYPTION_KEY
Seals every provider credential and platform setting stored in the database. Generate a 32-byte hex string:
EGMA_AUTH_SECRET
Signs session cookies. Any session minted without this secret will be invalid after a restart, so keep it stable.
EGMA_SIMULATOR_SERVICE_TOKEN
The token the simulator shows the API to claim simulation work. The API checks it on every claim request because the answers carry your live provider credentials.
egma_st_ so that secret scanners can recognise a leak. Set it in .env once and both the API container and the simulator container read it — they always match.
S3 credentials (four values)
Egma ships with a MinIO object store for voice simulation recordings. You need two credential pairs: one with write access (for the simulator to upload recordings) and one that is read-only (for the API to sign playback links).Summary of all ten required variables
Step 3 — Start the platform
Run the CLI’sself-host up command from your platform workspace:
- Generates the LiveKit API key and secret for your workspace, writes them to
.egma-platform/platform.env, and setsEGMA_BASE_URLto the printed address - Starts all containers and waits for the platform to answer
- Reports what the platform is still missing (provider configuration) and what is ready
http://localhost:3101, sign up, and claim the instance. You become the organization admin. The first person to sign up claims it — open signup closes behind them. Everyone after that arrives by invitation.
egma self-host up is not the same as docker compose up. The CLI version generates the media server credentials, waits for the platform to be healthy, and handles first-boot initialization automatically. Use egma self-host up every time you start the platform.Step 4 — Configure providers with egma self-host setup
Log in as the organization owner, then run the interactive setup wizard:
- LLM provider — who the simulator persona thinks with (e.g. OpenAI GPT-4o)
- TTS provider — what the persona speaks with (e.g. ElevenLabs)
- STT provider — what the persona hears with (e.g. Deepgram)
- Phone carrier — a Twilio account and number for phone simulations (optional — press Enter to skip)
EGMA_ENCRYPTION_KEY. Settings survive restarts, upgrades, and moves to another machine. A setting the platform already holds is never asked for again — running setup a second time after adding one new credential asks exactly one question.
Phone configuration (Twilio)
For phone simulation, the setup wizard asks for your Twilio account SID, an Auth Token, and a voice number already on your account — Egma never buys, ports, or registers numbers. The wizard shows a plan of what it will create before writing anything to your Twilio account. On approval it creates the SIP trunk, attaches your number and a credential, and writes the trunk details into the platform’s sealed store. The Auth Token is used once and kept nowhere afterward.Phone simulation requires the SIP gateway to be reachable from your carrier. On a server with a public IP or 1:1 NAT, set
EGMA_LIVEKIT_SIP_EXTERNAL_IP to your public address and open UDP port 5060 plus the RTP range (default 10000–10020) to your carrier’s IP ranges. On a laptop behind a home router, try it — Twilio supports symmetric RTP latching and many home routers work fine.Service URLs
After startup, the following services are available:
The simulator and grader publish no ports — they claim work outbound and need no inbound networking.
Receiving telemetry from your agent
Point your agent’s OTLP exporter at the API to stream production spans:Single-organization mode
By default, Egma runs in single-organization mode:/members page. If you are building a multi-tenant deployment, set this to false.
Adding a second user
Open/members in the web application, enter an email address, select a role, and send. If no SMTP server is configured, the invitation link comes back to you directly in the response — paste it to your colleague however you like (Slack, email, a text message).
To enable email delivery:
EGMA_SMTP_URL automatically enables email verification on signup and password-reset emails. There is no second setting to keep in step.
Default judge model
To give new projects a grading model without requiring them to configure one manually, set the three judge variables in.env:
Upgrading
Runegma self-host up again from your platform workspace after pulling the latest code. The API applies database migrations on boot. No manual migration step is required.
If you are upgrading from a release that used egma self-host phone setup, your old phone settings were stored in .egma-platform/platform.env. Nothing reads them there anymore — run egma self-host setup once to re-enter them. The file itself is kept because it also holds the LiveKit key and secret.
Troubleshooting
Platform refuses to start and names a missing variable
Platform refuses to start and names a missing variable
Every required variable is named in
.env.example. Make sure you have filled in all seven secrets listed in the table above. EGMA_LIVEKIT_API_KEY, EGMA_LIVEKIT_API_SECRET, and EGMA_BASE_URL are set automatically by egma self-host up — if they are missing, run egma self-host up instead of docker compose up.Recordings play nothing or return SignatureDoesNotMatch
Recordings play nothing or return SignatureDoesNotMatch
This means
EGMA_BLOB_PUBLIC_URL names a different host than the browser uses to reach the object store. Set it to the address a browser on your network actually reaches — for example, http://192.168.1.10:9000 if that is your server’s LAN address. Also verify that EGMA_BASE_URL and EGMA_BLOB_PUBLIC_URL both use the same scheme (http: or https:): a mixed-content mismatch silently blocks every recording.Egma self-host up works but the run never starts
Egma self-host up works but the run never starts
Check that
egma self-host setup has been run and that the platform reports no missing settings. A platform missing its persona model will accept runs but the simulator will error on every simulation. Run npx @egma/cli self-host setup --plan to see what is still unset.ClickHouse logs 'Too many open files'
ClickHouse logs 'Too many open files'
ClickHouse requires a higher file descriptor limit than a login shell grants. Copy the override file and restart:
Simulator waits forever and never claims work
Simulator waits forever and never claims work
Verify that
EGMA_SIMULATOR_SERVICE_TOKEN is set to the same value in .env that the API reads. If the token is missing or mismatched, the API rejects every claim request. Also confirm that EGMA_LIVEKIT_API_KEY and EGMA_LIVEKIT_API_SECRET are set — an empty value is refused at startup.Running the stack on a remote server (others need to reach it)
Running the stack on a remote server (others need to reach it)
Set
EGMA_BASE_URL to the address people reach the web application at — for example, http://192.168.1.10:3101. Set EGMA_BLOB_PUBLIC_URL to the address browsers reach the object store at — for example, http://192.168.1.10:9000. Set EGMA_S3_BIND=0.0.0.0 to publish the object store port. Both addresses must use the same scheme.