00
FL33T-rs on Railway
Customer operator · V12.6-style gate

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.

00a
Path A — pull public image (customer fleet)
No GitHub repo access required

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.

00b
Path B — Deploy from GitHub (Railway / operators)
Unchanged — Dockerfile + railway.toml

Railway connected-repo builds remain valid. Panels 01–04 below are Path B.

01
Steps (Path B)
One sitting
  1. 1 · New Railway project

    Open railway.appNew ProjectDeploy from GitHub → select your FL33T-rs repository. CLI alternative below.

  2. 2 · Builder = Dockerfile

    Railway should read railway.toml and use builder = "DOCKERFILE" with dockerfilePath = "Dockerfile". First build compiles the Rust service image.

  3. 3 · Postgres

    + NewDatabaseAdd PostgreSQL. Bind DATABASE_URL into the FL33T service as a reference variable (${{ Postgres.DATABASE_URL }}).

  4. 4 · Service variables

    Set the table in panel 02 below. JWT_SECRET must match the value on your aimanac-rs deployment for LLMGMT interoperability.

  5. 5 · Public URL

    Service → SettingsNetworkingGenerate Domain. Save the HTTPS origin; FL33T-iOS stores it after first-run setup.

  6. 6 · Deploy

    Push to the tracked branch or click Deploy. Railway promotes the new container only after GET /ready returns 200.

01b
CLI alternative
railway-cli  ·  the path maintainer ran 2026-05-18

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.

02
Environment variables
FL33T service
VariableRuleNotes
DATABASE_URLReference to Postgres pluginRequired for migrations + pool
APPLE_CLIENT_IDnet.llmtech.fl33tApple aud for FL33T
JWT_SECRET32-byte hex (persist)Must match aimanac-rs JWT_SECRET
JWT_REFRESH_SECRETSeparate hex secretFL33T-only refresh signing
JWT_EXPIRES_INe.g. 14dOptional
JWT_REFRESH_EXPIRES_INe.g. 30dOptional
RUST_LOGapi_server=infoOptional tracing
03
Health checks
Do not swap these probes
PathRoleHealthy signal
/healthLiveness200 + process-up JSON
/readyReadiness (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.

04
Verify from your laptop
curl
export FL33T_URL=https://YOUR-RAILWAY-DOMAIN.up.railway.app
curl -fsS "${FL33T_URL}/ready"
# expect: {"status":"ready","service":"fl33t-rs"}