Backend deployment
Backend and Admin Panel are two Railway services, described as code in .railway/railway.ts. Full detail lives in daily-meet-platform/docs/18_RAILWAY_DEPLOYMENT.md — this page is the quick-reference.
The golden rule
Change services/volumes/env through .railway/railway.ts (railway config plan to preview, railway config apply to apply) — not by clicking around the Railway dashboard. A dashboard edit still works, but it drifts out of sync with the file until someone runs railway config pull --force; skipping that step risks a later apply deleting a variable someone added by hand. This happened once already (2026-09-24) — a dashboard-added Cashfree/MSG91/Stream key set was about to be wiped by a blind apply.
One file, two environments
.railway/railway.ts encodes both testing and production using the railway/iac package's ctx.isEnvironment("production") pattern — not two separate files:
export default defineRailway((ctx) => {
const isProd = ctx.isEnvironment("production");
// ...
domains: [isProd ? "api.dailymeet.in" : "api-staging.dailymeet.in"],
source: github(..., { branch: isProd ? "production" : "main", ... }),
env: { ENVIRONMENT: isProd ? "production" : "staging", ... }
Switch which environment a command targets, then plan/apply as usual:
railway environment testing # or: railway environment production
railway config plan
railway config apply
Custom domains: a CLI quirk
railway config apply can only reflect a custom domain that already exists on a service — it can't create a brand-new one. To add one:
railway domain <domain> --service <name> --environment <env> # creates it, prints DNS records
railway config pull --force # picks it up into railway.ts
Service basics
| backend | admin-panel | wiki | |
|---|---|---|---|
| Root directory | backend | admin_panel | docs-site |
| Start command | uvicorn app.main:app --host 0.0.0.0 --port $PORT | uvicorn main:app --host 0.0.0.0 --port $PORT | Dockerfile (Caddy) — see below |
| Healthcheck | /health | — | — |
| Replicas | 1 (region iad) — do not scale until shared signaling coordination exists, see the RTC/WebRTC doc | 1 (region iad) | 1 (region iad) |
| Volumes | private-documents at /app/private_documents, per environment | — | — |
| Exists in | both environments | both environments | production only — one instance, not duplicated |
| Deploys from branch | main/production per environment | main/production per environment | always main, regardless of environment |
This page (and the rest of this wiki) is itself served this way — wiki.dailymeet.in is the wiki Railway service, built from docs-site/Dockerfile. Push to main and it redeploys automatically.
Database
A managed Railway Postgres service per environment — never shared. See Environments for the isolation guarantee and how it was verified.
Plan is safe, apply is not
railway config plan— read-only, never changes anythingrailway config apply— prompts before destructive changes; a stray--yesalone can't silently delete infrastructure without--confirm-destructivetoo
Promotion (releasing to production)
git checkout production
git merge main
git push origin production
That push is the entire release action — Railway auto-deploys both services in the production environment. Test on testing first; there's no additional CI gate.
Full detail
For sizing/backups, RTC/coturn deployment specifics, and the required pre/post-deploy checklist, see daily-meet-platform/docs/18_RAILWAY_DEPLOYMENT.md and docs/19_OPERATIONS_RUNBOOK.md in the platform repo.