1
Create the service
Choose New, then Docker Image, and enter
mahimairaja/voicegateway:0.24.0.The exposed port is optional: the image binds $PORT, which Railway sets, and the
healthcheck follows it. VOICEGW_PORT overrides both.2
Add Postgres
Choose New in the same project and add the PostgreSQL plugin.
3
Configure environment variables
In the app service’s Variables tab, add:
Paste
VOICEGW_DB_URL literally: Railway resolves the ${{Postgres.*}} references at
deploy time, so the password never leaves Railway.VOICEGW_API_KEY registers a wildcard ingest key without needing an auth.api_keys:
block in voicegw.yaml.4
Deploy
Redeploy after setting variables. HTTPS is automatic at
https://<your-service>.<your-project>.up.railway.app.Verify
Two checks. The first proves the deploy works, the second proves it is not open to the internet. Run both.1
A row survives a round trip
{"accepted":1}, then a body whose components.llm_ttft_ms is 447.0.This is the check that matters. Passing it proves the process runs, your key is
accepted, Postgres connected, migrations ran, and a write survives a read. Nothing
else needs to pass for the deploy to be good.2
The endpoint is not open to the internet
401. The check above proves your key is accepted; this one proves a request
without it is refused. /v1/ingest has to be publicly reachable for agents to push
to it, so anything other than 401 means anyone can write to your telemetry.If the round trip failed
Two commands tell you where.The round trip leaves one row behind, under project
verify. It carries no cost, so it
does not move your totals, but it does count as one request. No API call removes it:
DELETE /v1/projects/verify deletes a project’s configuration, not its recorded
requests. Run the check before you point real agents at the deploy and it stays easy to
ignore.collector_url and VOICEGW_API_KEY as
api_key. See Connect your agent.
Deploying from source instead
A clone or fork works too, with no build configuration:railway.json at the repository
root supplies the Dockerfile builder, its path, and healthcheckPath. Such a build
reports 0.0.0.dev0 at /health, because Railway passes no VERSION argument. It is
current, just unstamped.
Or let a coding agent do it
Runs every step on this page against the Railway CLI, including both checks.