This walkthrough mirrors the FL33T-rs deploy guide: repo-root Dockerfile, railway.toml pinned to DOCKERFILE, Postgres plugin, env vars, and a deploy gate on GET /ready (not /health).
Repo assumption: your connected GitHub repo ships Dockerfile at the root and railway.toml with healthcheckPath = "/ready" (matches public FL33T-rs layout). Forks should keep those paths or update Railway build settings accordingly.
Primary customer path: pull a pinned tag from GHCR, wire Postgres + JWT alignment with aimanac-rs, paste the HTTPS URL into FL33T-iOS.
export TAG=rust-cutover-20260520-ghcr-pipeline
docker pull ghcr.io/everplay-tech/fl33t-server:${TAG}
# compose: image: ghcr.io/everplay-tech/fl33t-server:${TAG} (not build: ./repo)
Tag pin: setup/llm. Package must be Public on GitHub Packages before anonymous pull works.
Railway connected-repo builds remain valid. Panels 01–04 below are Path B.
- 1 · New Railway project
Open railway.app → New Project → Deploy from GitHub → select your FL33T-rs repository. CLI alternative below.
- 2 · Builder = Dockerfile
Railway should read
railway.tomland usebuilder = "DOCKERFILE"withdockerfilePath = "Dockerfile". First build compiles the Rust service image. - 3 · Postgres
+ New → Database → Add PostgreSQL. Bind
DATABASE_URLinto the FL33T service as a reference variable (${{ Postgres.DATABASE_URL }}). - 4 · Service variables
Set the table in panel 02 below.
JWT_SECRETmust match the value on your aimanac-rs deployment for LLMGMT interoperability. - 5 · Public URL
Service → Settings → Networking → Generate Domain. Save the HTTPS origin; FL33T-iOS stores it after first-run setup.
- 6 · Deploy
Push to the tracked branch or click Deploy. Railway promotes the new container only after
GET /readyreturns 200.
Same outcome as the GitHub-deploy flow above; just executed from your local clone with the railway CLI. Project name should match the binary (fl33t-server), not the repo name (FL33T-rs).
cd FL33T-rs/ railway init --name fl33t-server # creates new Railway project railway up --detach # uploads source; Dockerfile build per railway.toml railway status # confirms project + environment + service link railway logs # tail build + runtime railway open # opens dashboard for env vars + domain
After railway up --detach kicks the first build, jump back to panel 02 to fill env vars in the dashboard and panel 03/04 to verify /ready goes green.
| Variable | Rule | Notes |
|---|---|---|
DATABASE_URL | Reference to Postgres plugin | Required for migrations + pool |
APPLE_CLIENT_ID | net.llmtech.fl33t | Apple aud for FL33T |
JWT_SECRET | 32-byte hex (persist) | Must match aimanac-rs JWT_SECRET |
JWT_REFRESH_SECRET | Separate hex secret | FL33T-only refresh signing |
JWT_EXPIRES_IN | e.g. 14d | Optional |
JWT_REFRESH_EXPIRES_IN | e.g. 30d | Optional |
RUST_LOG | api_server=info | Optional tracing |
| Path | Role | Healthy signal |
|---|---|---|
/health | Liveness | 200 + process-up JSON |
/ready | Readiness (DB ping) | 200 only when Postgres answers; Railway deploy gate |
If /ready returns 503, read the JSON reason class (db_pool_acquire_failed, db_query_failed, db_timeout) — then check Railway deployment logs; raw SQL errors stay in logs, not in the response body.
export FL33T_URL=https://YOUR-RAILWAY-DOMAIN.up.railway.app
curl -fsS "${FL33T_URL}/ready"
# expect: {"status":"ready","service":"fl33t-rs"}