relay CLI reference

The client covers bootstrap, diagnostics, deploys, auth, workspace sync, and admin work.

relay.js ships well beyond a thin deploy command. It supports socket and HTTP transport, browser-based login, relay doctor diagnostics, workspace pull, sync-based deploys with .relayignore, cached manifests, and local workspace fingerprints, lane-aware targeting, rollout inspection, rollback, app control, secrets, and buildpack plugin operations.

First local run
relay init --socket ./data/relay.sock --app demo --env dev
relay deploy --host-port 3005
relay pull          # sync server workspace back
relay status
relay projects
Command groups

The CLI surface breaks into seven concrete jobs.

This matches what relay.js actually exposes today: setup, deploy and inspect, slot control, version management, diagnostics, auth, and admin operations.

Bootstrap

Set project defaults with relay init, or run any command without a .relay.json and the interactive wizard starts automatically. The wizard prompts for connection details, app name, and environment, then writes the file. If an existing slot is already deployed under the same app/env/branch, the CLI warns and asks before overwriting.

Bootstrap
relay init --socket ./data/relay.sock --app demo --env dev
relay deploy

Ship and inspect

Deploy with sync-first uploads, then inspect the latest slot with status, logs, list, and projects. Build logs stream by default; pass --no-stream to suppress.

Ship and inspect
relay deploy --host-port 3005
relay pull                    # sync server workspace back to local
relay status
relay logs <deploy-id>
relay logs <deploy-id> --no-stream
relay list --app demo --limit 10
relay projects

Control the slot

Rollback or directly start, stop, and restart the running container for one app, env, and branch.

Control the slot
relay rollback
relay stop
relay start
relay restart

Version and updates

Check relay, relayd, and station versions from one command, then update agent binaries in place when a new release lands. Docker stays the default runtime; station is opt-in.

Version and updates
relay version
relay agent status
relay agent update

Doctor and setup checks

Run one operator-facing diagnostic before opening the dashboard. relay doctor checks the selected transport, local socket access, Docker reachability on same-machine installs, the agent health endpoint, version reporting, and the server-side doctor report that powers guided DNS and TLS setup.

Doctor and setup checks
relay doctor
relay doctor --socket ./data/relay.sock
relay doctor --url https://relay.example.com --token $RELAY_TOKEN

Auth

Log in through a browser flow to get a bearer token saved to ~/.relay-state.json, or log out to clear the saved session. Legacy token mode still works via RELAY_TOKEN or .relay.json.

Auth
relay login     # opens browser -> saves token
relay logout    # clears saved session

Admin surfaces

Manage app secrets and buildpack plugins from the CLI without opening the dashboard. Catalog search and verified remote plugin installs are available in the same surface. Signed-link sharing and promotion approval stay in the dashboard because they depend on lane policy and browser session context.

Admin surfaces
relay secrets list
relay secrets add --key DATABASE_URL --value postgres://...
relay plugin list
relay plugin search astro
relay plugin install ./astro-static.json
relay plugin install-url https://example.com/plugins/astro-static.json --sha256 <hex>
Transport modes

Use the socket locally. Use HTTP remotely.

The command set is the same either way. Only the transport and auth model change.

Socket transport

Use --socket or RELAY_SOCKET when the CLI runs on the same machine as relayd. No token is required because the socket is protected by filesystem permissions.

Socket transport
{
  "socket": "./data/relay.sock",
  "app": "demo",
  "env": "dev",
  "branch": "main"
}

HTTP transport

Use --url plus --token, or RELAY_URL and RELAY_TOKEN, when the CLI runs remotely. The client sends X-Relay-Token on each request.

HTTP transport
{
  "url": "http://127.0.0.1:8080",
  "token": "YOUR_TOKEN",
  "app": "demo",
  "env": "staging",
  "branch": "main"
}
Deploy path

relay deploy is a sync pipeline first, then a rollout.

The client does not tar the whole repo by default. It computes local state, filters with .relayignore, reuses cached hashes when possible, asks the agent what changed, uploads only the diff, then triggers the build, lane policy resolution, and container swap.

01

Start a sync session

relay deploy calls /api/sync/start, sends the saved workspace version plus a local fingerprint hint, receives a session_id, and prepares a staging area on the agent.

02

Hash, diff, upload

The CLI walks the workspace, applies .relayignore on top of built-in excludes, reuses cached hashes when size and mtime match, asks /api/sync/plan what changed, uploads only needed files, and posts deletes for stale paths.

03

Finish and stream

The final /api/sync/finish call triggers the build, lane policy resolution, and rollout. With --stream, the CLI follows /api/logs/stream/<id> until a terminal status arrives.

Deploy flags
relay deploy \
  --dir . \
  --mode port \
  --host-port 3005 \
  --service-port 3000 \
  --public-host demo-staging.relay.example.com \
  --install-cmd "npm ci" \
  --build-cmd "npm run build" \
  --start-cmd "node server.js" \
  --no-stream

Important implementation detail

env can target production, staging, dev, or preview. The compiled CLI default is still preview when you do not set one.

traffic_mode and access_policy exist on the server, but they are stored through app config and lane policy, not as relay deploy flags.

preview_url comes back from the deploy record after rollout, even when the lane is staging or dev. The field name stayed the same for compatibility.

The setup wizard now prompts for docker or station. The legacy vessel label is gone from the visible CLI surface.

.relayignore is project-local and only affects sync uploads. Built-in excludes still apply so node_modules, git state, and Relay metadata stay out of the deploy manifest.

The CLI saves a local workspace fingerprint, so a stale saved base version does not force a pull when your local repo is clearly newer and has diverged.

status, list, and projects are read-only views over the same deploy and app state tables the dashboard uses.

Streaming log flow
GET /api/logs/stream/<deploy-id>

event: message
data: {"message":"selected buildpack: node-next"}

event: deploy-status
data: {"status":"running"}
Config resolution

Flags win, then project config, then environment variables.

resolveDeployArgs and resolveTransport both follow the same layered model, which keeps debugging straightforward.

1

CLI flags

Explicit flags like --socket, --url, --token, --app, and --branch override everything else for one invocation.

2

.relay.json

Project-local defaults written by relay init or the interactive setup wizard.

3

Environment variables

RELAY_SOCKET, RELAY_URL, RELAY_TOKEN, RELAY_APP, RELAY_ENV, and RELAY_BRANCH.

4

Compiled defaults

url defaults to http://127.0.0.1:8080, env to preview, and branch to main. preview remains the CLI fallback, even though the server supports four first-class lanes.

5

Build hints

relay.config.json is read for install_cmd, build_cmd, start_cmd, service_port, and optional monorepo fields such as project_root, build_context, and dockerfile when deploying.

6

Sync filters

.relayignore augments Relay's built-in excludes for deploy manifests. Hash reuse is local-only and keyed from saved workspace state so unchanged files do not get re-hashed every deploy.

.relay.json
{
  "socket": "./data/relay.sock",
  "app": "demo",
  "env": "dev",
  "branch": "main",
  "dir": "."
}
Recent additions

The docs now cover lanes, access policy, auth, and the real transport model.

First-class lanes

The CLI can target production, staging, dev, or preview, while the server applies lane policy defaults for routing, retention, and promotion.

Edge access defaults

dev and staging default to relay-login on the server. The CLI only picks the lane; the edge policy is enforced centrally by relayd.

Browser login flow

relay login opens a browser tab, you authenticate once, and the bearer token is saved to ~/.relay-state.json. relay logout clears it.

relay pull

Downloads the current server workspace as a tar archive and writes it to the local directory. Useful when the server has diverged or after pulling on another machine.

Workspace version check

relay deploy still sends base_version with each sync, but it also sends a local fingerprint hint. If the server workspace is ahead and your local repo has diverged too, Relay can continue with the newer local content instead of reflexively forcing pull or force.

relay doctor

Run one command to validate transport, auth shape, agent reachability, version reporting, Docker reachability on same-machine installs, and the new server-side doctor report.

.relayignore and cached manifests

The sync pipeline now respects a project-level .relayignore and reuses saved hashes when size and mtime are unchanged, which cuts repeat deploy overhead on larger repos.

Interactive setup wizard

Any command can bootstrap .relay.json when config is missing and stdin is a TTY.

Socket-first local auth

The CLI can skip tokens entirely on the same machine by targeting relay.sock.

Docker default engine

The setup wizard and docs now use docker and station consistently. Docker remains the default runtime, and station is still only selectable when you choose it deliberately.

Dashboard-owned promotion flow

Promotion requests, owner approvals, signed-link generation, and lane expiry visibility live in the dashboard because those workflows depend on persistent lane state rather than one-shot deploy flags.

Version visibility

relay version reports CLI, installed binaries, latest release, and server version data from /api/version when reachable.

status, list, and projects

Read deploy history and project inventory without opening the dashboard. list accepts --limit to cap results.

Secrets and plugin admin

Manage app secrets and buildpack plugins directly from the CLI, including catalog search and verified HTTPS installs with optional SHA256 pinning.

Streaming on by default

relay deploy and relay logs stream build output without any flag. Pass --no-stream to suppress live output and print the log ID instead.