CLI
Deploye, verfolge Logs, führe Befehle aus und verwalte Apps von deinem Terminal aus.
railyard ist eine einzelne Go-Binary über der Railyard REST API:
deploye, verfolge Logs, führe Befehle aus, verwalte Umgebungsvariablen, Domains, Datenbanken und
Server von deinem Terminal aus. Keine Runtime erforderlich.
Installation
Eine Binary, keine Abhängigkeiten, für macOS und Linux auf arm64 und amd64. Nichts ist hardcodiert — die CLI spricht mit dem Railyard, bei dem du dich anmeldest.
brew install almokhtarbr/railyard/railyard # Homebrew
curl -fsSL https://app.railyard.run/install.sh | sh # one-line installer (verifies the sha256)
Später, statt brew upgrade:
railyard upgrade # replaces this binary with the newest build your Railyard serves
railyard version # prints the installed build
Anmelden
railyard login
Confirm code ABCD2345 in your browser: https://app.railyard.run/cli/auth/ABCD2345
Logged in to https://app.railyard.run
Das ist der Device-Flow (gleiches Prinzip wie gh auth login oder fly auth login):
Die CLI öffnet diese URL in deinem Browser, du tippst den im Terminal angezeigten Code
in das bereits angemeldete Dashboard ein, und die CLI holt sich ein für dich erstelltes
Token — nie wird ein Passwort oder Token ins Terminal eingetippt. Sie meldet sich bei
app.railyard.run an; setze RAILYARD_API, um sie woanders hinzeigen zu lassen.
Deine API-Tokens, SSH-Keys, Cloud-Konten und Git-Provider findest du auf einer Seite im Dashboard: Settings → Access & tokens (app.railyard.run/access).
railyard whoami # team, token scope, limits (alias: me)
railyard logout # forget the saved token
Konfiguration und CI
Das Token und die API-URL werden in ~/.railyard/config.json gespeichert (Modus 0600).
Für CI oder Container überspringe login und setze stattdessen Umgebungsvariablen —
sie haben immer Vorrang vor der Datei:
| Variable | Überschreibt |
|---|---|
RAILYARD_API (oder RAILYARD_API_URL) | die Control-Plane-URL |
RAILYARD_TOKEN | das Bearer-Token |
RAILYARD_CONFIG | den Pfad der Konfigurationsdatei (Standard ~/.railyard/config.json) |
--json bei jedem Befehl gibt die rohe API-Antwort statt einer Tabelle aus.
Eine App mit einem Verzeichnis verknüpfen
cd my-app && railyard link my-app # writes ./.railyard.json: {"app": "my-app"}
railyard deploy --follow # app argument now optional in this directory
railyard unlink
Befehle, die [app] akzeptieren, fallen auf die verknüpfte App zurück, gefunden, indem
vom aktuellen Verzeichnis aus nach oben zur ersten .railyard.json gegangen wird. Überall
sonst ist <app> eine ID oder ein Name (ein eindeutiges Präfix funktioniert auch).
Shell-Completion
railyard completion zsh > "${fpath[1]}/_railyard"
railyard completion bash > /etc/bash_completion.d/railyard
railyard completion fish > ~/.config/fish/completions/railyard.fish
Apps
railyard apps
railyard app [app]
railyard open [app]
railyard create <name> <git-url> [flags]
railyard templates [--verified]
railyard launch <template> [--server id]
railyard clone [app]
railyard promote [app]
apps— id · Name · Status des letzten Deploys · URL, eine Zeile pro App.app— vollständiges JSON für eine App.open— gibt die URL der App aus und öffnet sie in deinem Browser.create-Flags:--server <id|hostname>,--ref <branch>,--port <n>(wird aus dem Repo erkannt, wenn ausgelassen),--addons postgres,redis,…,--db-extensions <ext,…>.templates— der One-Click-Katalog;launchdeployt gleich eines.clone— kopiert die App in eine Staging-Kopie;promotebringt das Release einer Staging-App in Produktion (wie Heroku-Pipelines).
railyard create my-app https://github.com/me/my-app --ref main --port 3000
railyard clone my-app && railyard promote my-app-staging
Deploys
railyard deploy [app] [flags]
railyard deploys [--app <app>] [--status <s>]
railyard deploy:logs <id> [--follow]
railyard deploy:approve|reject|cancel <deploy-id>
railyard releases [app]
railyard rollback <app> <version> [--code-only] [--message "note"]
railyard deploy-window <app> off | <mon,tue,...> <09:00> <17:00> [zone]
deploy-Flags: --ref <branch|tag|sha> deployt diese Referenz einmalig ohne
den verfolgten Branch zu ändern, --message "note", --follow streamt das
Build- und Release-Log, --force überspringt First-Deploy-Checks, --at <ISO 8601>
plant den Deploy (abbrechen mit deploy:cancel), --anyway deployt außerhalb des
Deploy-Fensters.
deploy --local baut das aktuelle Verzeichnis mit deinem Docker statt mit
dem Builder des Teams, pusht das Ergebnis und deployt dieses Image einmalig — wie
fly deploy --local-only:
railyard deploy [app] --local [--image repo[:tag]]
--image pusht in deine eigene Registry (dein docker login) statt in die
Build-Registry des Teams; ein nicht getaggtes Repo bekommt :local-<UTC timestamp>.
deploy-window — Pushes und Auto-Deploys außerhalb des Fensters warten, bis es
öffnet; deploy --anyway überschreibt das. rollback deployt den Commit eines
früheren Releases erneut und stellt dessen Umgebungsvariablen wieder her
(--code-only behält die heutigen).
railyard deploy --ref v1.4.2 --message "hotfix" --follow
railyard rollback my-app 112 --message "bad migration"
railyard deploy-window my-app mon,tue,wed,thu,fri 09:00 17:00 America/New_York
Git-Deploys
railyard git:remote [app] [--remote name]
railyard git:strict <app> on|off
git:remote fügt ein railyard-Git-Remote hinzu, das auf diese App zeigt, sowie
einen Git-Credential-Helper, der mit deinem Token antwortet, sodass git push railyard main
genau diesen Commit deployt und das Build-Log zurückstreamt. git:strict
(standardmäßig an) lehnt einen Push ab, dessen Build fehlschlägt, sodass der Branch
auf seinem alten Commit bleibt; off nimmt den Push zuerst an und deployt danach.
cd my-app && railyard git:remote
git push railyard main
Jeder Push ist auf 1 GB begrenzt. Gepushte Repositories zählen außerdem gegen ein
Team-weites Kontingent (standardmäßig 5 GB); wird es überschritten, lehnt das den Push
mit der Nutzung und einem Vorschlag ab, Apps zu löschen, zu denen du nicht mehr pushst.
Railyard führt jede Nacht git gc auf gepushten Repositories aus, um sie klein zu halten.
Runtime
railyard logs [app] [--follow] [--process web] [--tail 200]
railyard logs:search <app> <text|/regex/> [--level error] [--range 24h] [--process web]
railyard ps [app]
railyard restart [app] [--process web]
railyard run <app> [--process worker] [--exec] -- <command...>
railyard scale <app> <process>=<n> …
railyard wake [app]
railyard sleep <app> <10|30|60|360|1440|off>
run startet einen frischen One-off-Container aus dem aktuellen Release (wie
heroku run), oder führt mit --exec innerhalb des bereits laufenden Containers aus;
es streamt die Ausgabe und beendet sich mit dem Exit-Code des entfernten Befehls.
sleep stoppt die Container der App nach dieser Anzahl Leerlaufminuten, und
wake/der nächste Request holt sie zurück; off deaktiviert das.
railyard logs my-app --follow --process web
railyard run my-app -- bin/rails db:migrate
railyard scale my-app web=2 worker=1
railyard sleep my-app 30
Konfigurationsvariablen und Domains
railyard env [app] [--reveal[=KEY]]
railyard env:set <app> KEY=VALUE …
railyard env:unset <app> KEY
railyard configs
railyard domains [app]
railyard domain:add <app> <hostname> [--redirect]
railyard domain:rm <app> <domain-id>
env maskiert Werte, außer bei --reveal (alle) oder --reveal KEY (einer).
configs listet teamweite Konfigurationseinträge auf (read-only von der CLI aus).
railyard env my-app --reveal SECRET_KEY_BASE
railyard env:set my-app RAILS_ENV=production LOG_LEVEL=info
railyard domain:add my-app www.example.com --redirect
Datenbank und Volumes
railyard db:query <app> "<sql>" [--write]
railyard db:backups [app]
railyard db:backup [app]
railyard db:restore <backup-id>
railyard db:url <backup-id>
railyard volumes [app]
railyard volume:backup <app> <volume-name>
railyard volume:restore <backup-id>
db:query ist read-only, außer bei --write (benötigt ein write-berechtigtes Token).
db:url gibt einen signierten Download-Link für ein Backup zurück.
railyard db:query my-app "select count(*) from users"
railyard db:backup my-app
railyard volume:backup my-app data
Manifest
railyard manifest:pull [app] [--secrets] [--out railyard.yml]
railyard manifest:apply [app] <file.yml>
railyard manifest:validate [file.yml]
manifest:pull gibt die App als railyard.yml aus (--secrets schließt
Variablenwerte ein); manifest:apply wendet eine solche auf die App an.
manifest:validate prüft eine lokale Datei (./railyard.yml wenn ausgelassen),
ohne sie anzuwenden oder überhaupt eine App zu benötigen — unbekannte Keys bekommen
einen Vorschlag (contaner_port →
“did you mean container_port?”); beendet sich mit 0 und gibt “is valid” aus, wenn es
keine Probleme gibt, sonst mit 1 und listet sie auf.
railyard manifest:pull my-app --out railyard.yml
railyard manifest:apply my-app railyard.yml
railyard manifest:validate railyard.yml
Observability
railyard metrics [app] [--range 1h|24h|7d|30d]
railyard autoscale <app> --max N [--min N] [--p95 ms] [--cpu %]
railyard autoscale <app> off
metrics gibt Requests, p95, Fehlerrate und die langsamsten Endpoints aus.
autoscale skaliert Web-Replicas zwischen --min/--max, sobald die p95-Latenz
oder CPU die angegebenen Schwellenwerte überschreitet; off entfernt die Grenzen.
railyard metrics my-app --range 7d
railyard autoscale my-app --max 5 --min 1 --p95 300 --cpu 80
Benachrichtigungen und Webhooks
railyard notify
railyard webhooks
Teamweite Listen von Benachrichtigungsregeln und Webhook-Endpoints (read-only von der CLI aus; erstellen und bearbeiten geht über das Dashboard).
Server
railyard servers
railyard server <id>
railyard server:cordon <server-id>
railyard server:uncordon <server-id>
railyard server:reboot <server-id>
railyard server:power-cycle <server-id>
railyard server:prune <server-id>
railyard server:resize <server-id> <size>
cordon verhindert, dass neue Apps auf einem Server platziert werden, ohne das
zu verschieben, was bereits dort läuft; prune räumt ungenutzte Docker-Images und
Volumes auf.
railyard server:cordon srv-7
railyard server:resize srv-7 s-4vcpu-8gb
Networking
railyard tunnel [app] [web|db|postgres|redis|<process>] [-p local-port]
Alias: proxy. Leitet einen lokalen Port an einen Container oder eine Datenbank
auf dem Server der App weiter — wie fly proxy / railway connect. Lauscht auf
localhost (standardmäßig auf dem entfernten Port); ein Datenbank-Tunnel gibt eine
fertige postgres://…@localhost:<port>/…-URL aus. Nichts wird ins Internet
geöffnet: Bytes reisen von CLI → Control Plane (dein Token) → Agent → Container.
railyard tunnel my-app db -p 5433
Suche und Imports
railyard search:reindex [app]
railyard import
search:reindex führt den Reindex-Befehl der App in einem frischen One-off-Container
aus. import öffnet den Heroku/Render/Fly-Importer in deinem Browser.
Exit-Codes
0 ok · 2 die API hat einen Fehler zurückgegeben (Meldung auf stderr) · 3 nicht
angemeldet oder falsche Nutzung · 64 falsche Befehlsnutzung. railyard run beendet
sich stattdessen mit dem eigenen Exit-Code des entfernten Befehls.
Siehe auch
docs/API.md— die REST API, mit der die CLI spricht.