| name | openfdd-railway-cli |
| description | Use when installing, authenticating, linking, or re-pinning the Open-FDD Railway hub (central/mqtt/web) via the Railway CLI on bensbench. Triggers on: railway CLI, RAILWAY_TOKEN, railway login, railway link, railway redeploy, Railway re-pin, OPENFDD_NGINX_RESOLVER, sha tip on Railway, gleaming-cooperation. |
Railway CLI (Open-FDD hub)
Full ops: docs/operations/RAILWAY_DEPLOYMENT.md
Checklist: RAILWAY_DEPLOYMENT_CHECKLIST.md
Not Open-FDD MCP. Railway CLI / Railway’s optional MCP manage cloud deploys. HVAC FDD tools stay in mcp/ (openfdd-mcp + agent JWT to private central).
Verified host state (bensbench, 2026-09-01)
| Item | Value |
|---|
| Package | @railway/cli via npm i -g @railway/cli |
| Auth | railway login (browser) — verified; optional RAILWAY_TOKEN in ~/.config/railway/bensbench.env |
| Link | ~/open-fdd → project gleaming-cooperation, env production |
| Current hub pin | sha-3c9f753 / 3.3.15+3c9f75311ae1 (re-pin after each Phase 7 fix publish) |
| Last backup | ~/openfdd-backups/railway/20260901T144551Z/ |
Live services (names matter for CLI)
| Railway service name | Role | Notes |
|---|
openfdd-central-cQ-F | central | Private; DNS openfdd-central-cQ-F.railway.internal:8080 |
openfdd-mqtt | mqtt | Private MQTTS |
openfdd-web | web | Public SPA; OPENFDD_CENTRAL_UPSTREAM=openfdd-central-cQ-F.railway.internal:8080 |
Always railway status / railway service list before re-pin — do not assume the central service is literally named openfdd-central.
Post-auth snapshot (pre tip re-pin): mqtt Online on sha-3395551; web Crashed with invalid port in resolver "fd12::10" (needs tip openfdd-web:sha-9667888 + OPENFDD_NGINX_RESOLVER=auto).
Patch train (bosspi → Railway + Phase 7 local gates)
Do not treat bensbench dual-MQTT as the cloud gate. After each tiny rev / ops fix:
- Tip Actions green + GHCR Publish (
sha-* == nightly digest)
- GH tidy (0 open PRs; delete feature branch)
- Re-pin central → mqtt → web; bosspi fieldbus arm64 to same
sha-*
- Gates: L1
/api/health → L3 mqtt Online + ingest → L4 Pi has_telemetry → stream healthy → L5 FDD
- Local bench: re-stress only the gate(s) fixed (
scripts/nightly-ot-bench/<gate>.sh); full run_all when Phase 7 queue is empty
- Sync
BUG_REPORT_OT_MODBUS_HAYSTACK.md — log FAIL before fix; move to patched when green; Railway F1 under separate table
MQTT certs: railway volume add on openfdd-mqtt at /mosquitto/certs, upload ca.pem + server cert/key. Pi reachability: railway tcp-proxy create --port 8883 --service openfdd-mqtt (human-approved) or VPN. Never commit PEMs/tokens.
Non-negotiables
- Never commit
RAILWAY_TOKEN, JWTs, or Railway variable dumps.
- Prefer GHCR
sha-<7> (same tip as bench soak). Sticky :nightly only after digest match.
- Deploy order: central healthy → mqtt → web. No fieldbus on Railway.
- Keep
OPENFDD_CENTRAL_UPSTREAM aligned with the actual central service DNS name.
- Railway AI / Railway MCP ≠ Open-FDD FDD agent.
- Optional
railway setup agent installs Railway’s Cursor skills/MCP — OK if human asks; still follow this skill + AGENTS.md.
Agent workflow
command -v railway || npm i -g @railway/cli
railway --version
railway whoami || railway login
cd ~/open-fdd
railway status >/dev/null 2>&1 || railway link
SHA=sha-91fb350
CENTRAL_SVC=openfdd-central-cQ-F
railway service source connect --service "$CENTRAL_SVC" \
--image "ghcr.io/bbartling/openfdd-central:${SHA}"
railway service source connect --service openfdd-mqtt \
--image "ghcr.io/bbartling/openfdd-mqtt:${SHA}"
railway variable set OPENFDD_NGINX_RESOLVER=auto --service openfdd-web
railway variable set OPENFDD_PARQUET_ROOT=/workspace/openfdd --service "$CENTRAL_SVC"
railway service source connect --service openfdd-web \
--image "ghcr.io/bbartling/openfdd-web:${SHA}"
Smoke: public SPA + https://<web>/api/health. Sidebar version must match tip (3.3.11+91fb350…).
Dual pipeline: bosspi → Railway only; bensbench local react stack (OPENFDD_IMAGE_TAG=sha-* pull, --no-pull) for firewall/on-prem. Do not cross-wire edges for the parity gate.
BACKUP before every central re-pin (hard gate)
cd ~/open-fdd
./scripts/railway_central_workspace_backup.sh
Re-pin = image tag only. Never delete/recreate the /workspace volume. Docs: backup-update-restore.md.
Always pin tip after Publish: production showing 3.3.9+2dce59a while tip is newer is an automatic P0 fail. After GHCR Publish, re-pin central + mqtt + web + bosspi fieldbus to the same sha-<7>.
OT floor (bosspi)
OPENFDD_FIELDBUS_POLL_INTERVAL_SECS=60 and OPENFDD_MQTT_PUBLISH_INTERVAL_SECS=60. Never set OPENFDD_FIELDBUS_DEV_FAST_POLL=1 in production.
Data model (empty Overview)
Empty charts/FDD with healthy ingest_ok ⇒ missing roles (zonetemp/sa_t must normalize to zone_t/sat), not broken nginx. See package-mapping skill + normalize_role in fdd_core.
Anti-patterns
- Logging
railway variable list --json (secrets) into SESSION_LOG / chat.
- Hard-coding
--service openfdd-central when the live name is openfdd-central-cQ-F.
- Re-pinning web before central is healthy.
- Re-pinning central without a workspace backup.
- Deploying
openfdd-fieldbus on Railway for BACnet.
- Confusing Railway CLI/MCP with
openfdd-mcp FDD tools.
- Leaving hub on a stale
sha-* after tip Publish.