Railway Deployment¶
Use Railway when you want a managed evaluation deployment with DeltaLLM, PostgreSQL, and Redis created from one template.
The durable deployment artifact is a Railway Template. After the template is published, the repository README should link to the published template URL with Railway's deploy button.
Do not merge a README button with a placeholder URL.
Railway's deploy button uses the published template code:
<a href="https://railway.com/deploy/<template-code>?utm_medium=integration&utm_source=template&utm_campaign=deltallm">
<img src="https://railway.com/button.svg" alt="Deploy on Railway" height="40">
</a>
Template Services¶
Create the template with three services:
| Service | Source | Notes |
|---|---|---|
deltallm |
GitHub repo or published deltallm/deltallm:<release> image |
Uses deploy/railway/Dockerfile, public HTTP networking, and /health/readiness |
Postgres |
Railway PostgreSQL service | Referenced by the app through DATABASE_URL |
Redis |
Railway Redis service | Referenced by the app through REDIS_URL and DELTALLM_REDIS_URL |
Prefer the GitHub repo source for the first template so Railway can track template updates from the repository. Pin a released branch or tag when publishing a stable template.
App Service Settings¶
The repository includes railway.toml with the app service defaults:
[build]
builder = "DOCKERFILE"
dockerfilePath = "deploy/railway/Dockerfile"
[deploy]
healthcheckPath = "/health/readiness"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
Do not hard-code PORT. Railway provides PORT at runtime, and deploy/railway/Dockerfile starts uvicorn with that value.
The Docker image default config path is intended for Docker Compose bind mounts. Railway must set:
config.example.yaml is included in the image and is safe for a first-run Railway deployment because its secrets are environment-backed.
Template Variables¶
Configure these variables on the deltallm service:
DELTALLM_CONFIG_PATH=/app/config.example.yaml
DATABASE_URL=${{Postgres.DATABASE_URL}}
REDIS_URL=${{Redis.REDIS_URL}}
DELTALLM_REDIS_URL=${{Redis.REDIS_URL}}
DELTALLM_MASTER_KEY=<user input, 32+ characters with letters and digits>
DELTALLM_SALT_KEY=${{secret(64)}}
PLATFORM_BOOTSTRAP_ADMIN_EMAIL=<user input>
PLATFORM_BOOTSTRAP_ADMIN_PASSWORD=<user input, 12+ characters>
OPENAI_API_KEY=<optional user input>
Variable notes:
DELTALLM_MASTER_KEYmust be supplied by the deployer, must be at least 32 characters, and must include letters and digits. This is the initial gateway credential for API calls.DELTALLM_SALT_KEYmust be unique and must not bechange-me.PLATFORM_BOOTSTRAP_ADMIN_EMAILandPLATFORM_BOOTSTRAP_ADMIN_PASSWORDcreate the initial browser-login admin account.- Use an initial admin password with at least 12 characters so the first-login password-change flow can complete cleanly.
OPENAI_API_KEYis optional. Supplying it makes the startergpt-4o-minideployment usable immediately.
First Deploy¶
- Open the published Railway Template URL.
- Review the
deltallm,Postgres, andRedisservices. - Fill in the required admin variables.
- Optionally set
OPENAI_API_KEY. - Deploy the template.
- Wait for the
deltallmservice healthcheck to pass. - Open the generated public domain for the
deltallmservice.
The first boot runs Prisma migrations before starting the API:
The bootstrap retries database connectivity and then runs strict prisma migrate deploy.
Post-Deploy Checks¶
Set APP_URL to the public Railway domain:
Check readiness:
Expected response:
Log in to the Admin UI at APP_URL with:
PLATFORM_BOOTSTRAP_ADMIN_EMAILPLATFORM_BOOTSTRAP_ADMIN_PASSWORD
The bootstrap account may require a password change before you can use the rest of the Admin UI.
If OPENAI_API_KEY was supplied, verify the starter model:
export DELTALLM_MASTER_KEY="<the value you entered during template deploy>"
curl "$APP_URL/v1/models" \
-H "Authorization: Bearer $DELTALLM_MASTER_KEY"
Send a chat request:
curl "$APP_URL/v1/chat/completions" \
-H "Authorization: Bearer $DELTALLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "Hello from Railway"}
]
}'
If OPENAI_API_KEY was omitted, the app should still boot. Use the Admin UI to add a provider credential and update or create model deployments before sending gateway requests.
Redeploy Behavior¶
Redeploys are designed to be idempotent:
- Prisma runs
migrate deploy, so already-applied migrations are skipped. - PostgreSQL data persists in the Railway PostgreSQL service.
- Redis state is external to the app service.
- Model bootstrap inserts the
config.example.yamlmodel list only when the model deployment table is empty.
If a redeploy fails at migration time, inspect the deltallm deploy logs first. Do not use prisma db push against a Railway database; resolve migration history and rerun the deployment.
Adding Providers And Models¶
After the app is running:
- Open the Admin UI.
- Go to the model deployment area.
- Add or update provider credentials.
- Create model deployments or update the starter
gpt-4o-minideployment. - Re-run
/v1/modelsand a chat completion check.
For production-oriented deployments with dedicated batch workers, shared artifact storage, custom domains, and stricter operational controls, create a separate template rather than extending this evaluation template.
Release Automation¶
The release workflow can publish or update the Railway template marketplace metadata after a GitHub Release is published.
Configure these repository settings before enabling the README deploy button:
| Setting | Type | Required | Notes |
|---|---|---|---|
RAILWAY_API_TOKEN |
GitHub Actions secret | Yes | Railway account or workspace token with template publishing access |
RAILWAY_TEMPLATE_ID |
GitHub Actions variable | Yes | Stable template ID returned by the initial Railway template creation |
RAILWAY_TEMPLATE_WORKSPACE |
GitHub Actions variable | Optional | Workspace ID or name, useful when the token can access multiple workspaces |
RAILWAY_TEMPLATE_DEMO_PROJECT |
GitHub Actions variable | Optional | Public demo project ID to show on the template page |
The release workflow intentionally updates an existing reviewed template. It does not create a fresh template from a live smoke-test project on every release because that can accidentally copy test-only variables, source settings, or one-off infrastructure state.
Before the first automated publish:
- Create the Railway template from a clean project whose
deltallmservice is connected to the public GitHub repository. - Confirm the template has the service graph and variables documented above.
- Store the returned template ID in
RAILWAY_TEMPLATE_ID. - Add
RAILWAY_API_TOKENas a GitHub Actions secret. - Run the next release workflow.
- Copy the published template URL into the README button.