First-class lanes
Relay ships with production, staging, dev, and preview lanes. Each lane carries defaults for routing, retention, promotion, and browser access instead of relying on scattered env checks.
Relay keeps the path from local repo to running container short and inspectable: lane-aware routing, protected edge access, signed sharing, expiring temporary lanes, staged promotion, streamed logs, rollback-ready images, build tracking, user accounts, and secrets encryption.
Protected dev and staging environments.
Self-hosted product teams.
Operators who care about where the container actually lives.
Relay ships with production, staging, dev, and preview lanes. Each lane carries defaults for routing, retention, promotion, and browser access instead of relying on scattered env checks.
Choose public, relay-login, signed-link, or ip-allowlist per lane. dev and staging default to Relay-auth gated access so internal environments stay internal.
Upload only changed files using workspace manifests instead of re-sending entire projects on every deploy.
Build an image, start the next blue or green slot, switch traffic only after readiness passes, then drain the previous slot before cleanup.
Every deploy gets a sequential build number per app. The dashboard shows who triggered each deploy, the commit message for webhook-driven builds, and full duration history.
Create owner, deployer, and viewer accounts with username/password auth. The first boot prompts for an owner account. CLI login uses a browser exchange flow to issue a bearer token.
Set RELAY_SECRET_KEY and secrets in relay.db are encrypted with AES-256-GCM. The deploy path decrypts transparently. Existing plain-text secrets continue to work during migration.
Deploy triggers, secret writes, user creation, and role changes are all recorded with actor, target, and timestamp. The Server tab surfaces the recent activity trail.
Spin up companion Postgres, Redis, MySQL, or Mongo services from relay.json. On Docker lanes they share a Docker network. On Station lanes, Relay injects host aliases so the app resolves service names through /etc/hosts.
Built-in buildpacks cover mainstream app types including Sprint UI. Server-installed plugins still handle extra framework shapes when needed.
Run in direct port mode or through Relay's built-in edge plus Caddy proxy stack. staging gets a stable host, while dev and preview can generate random managed aliases automatically.
signed-link lanes can now mint a temporary share URL from the dashboard. Relay signs relay_exp and relay_sig centrally and the edge verifies them before the app responds.
dev and preview lanes can expire automatically. Relay refreshes their retention window on deploy or restart, then stops stale lanes in the background so temporary environments do not linger forever.
staging can promote the already-validated image into production, pause for owner approval when needed, then watch health and queue rollback automatically if the target lane fails after handoff.
Container build, run, stop, network, volume, and log operations all route through a ContainerRuntime interface. Docker is the default backend. Station stays available per-app as an experimental runtime.
Restart, stop, stream logs, inspect deploy history, manage app config, and view the activity log from the same control surface.
Relay supports both a user-account model with roles and a legacy single-token mode for existing deployments. App traffic can also be gated with lane-level edge access policies, while secrets remain encrypted at rest and every significant action lands in the audit log.
Full access: deploy, manage secrets, create and remove users, change roles.
Can trigger deploys and manage secrets. Cannot manage user accounts.
Read-only dashboard access. Cannot trigger deploys or edit secrets.
Set each lane to public, relay-login, signed-link, or ip-allowlist. dev and staging default to relay-login so browser access stays scoped to Relay users.
signed-link lanes can mint temporary share URLs directly from the dashboard instead of relying on operators to hand-build tokens.
Set RELAY_SECRET_KEY to store secrets as AES-256-GCM ciphertext. Key is derived via SHA-256 so any string length works. Unencrypted values are still read during the transition.
Every deploy, promotion request, secret write, user create, delete, and role change is appended with actor plus timestamp. Exposed at GET /api/audit and visible in the Server tab.
# User accounts (recommended)
# First boot -> dashboard setup wizard
# Add users from Server -> User Management
# CLI browser login
relay login
# Legacy single-token (still supported)
RELAY_TOKEN=your-token relayd
# Secrets encryption
RELAY_SECRET_KEY="strong-passphrase" relaydEach deploy is assigned the next sequential build number for that app. The dashboard surfaces who triggered each deploy and the commit message for git-push builds, making it easy to trace any running container back to a change.
Auto-incremented per app and shown as #42 in the dashboard instead of a UUID fragment.
The authenticated username is stored with every CLI-triggered deploy and shown alongside the build number.
For GitHub webhook deploys, the first line of head_commit.message is stored and shown in the deployments list.
started_at and ended_at are tracked per deploy so average build time is computable across any filter set.
Each deploy records whether it came from sync or git, surfaced as a badge in the dashboard.
The deployment search includes commit message and deployer name alongside branch, commit SHA, and image tag.
{
"id": "f3a2...",
"build_number": 42,
"app": "my-app",
"env": "staging",
"branch": "main",
"status": "success",
"deployed_by": "alice",
"commit_message": "fix: auth middleware",
"commit_sha": "a1b2c3d",
"source": "sync",
"created_at": "...",
"started_at": "...",
"ended_at": "..."
}The rollout path in relayd starts the next slot, waits for readiness, flips traffic to that slot, and drains the previous slot for a configurable window. In edge proxy mode, traffic can run as edge or session, and access policy is enforced before the app responds.
App containers are named per slot and alternate between blue and green on each successful rollout.
Traffic only moves after the candidate slot is reachable on its service port.
The previous slot is kept alive for RELAY_ROLLOUT_DRAIN_SECONDS before cleanup.
traffic_mode=edge sends everyone to the active slot immediately after the switch.
traffic_mode=session sets a cookie and can keep a client pinned to either the active or standby slot during the drain window.
access_policy is evaluated before the request reaches the active slot, so Relay Login, signed links, and allowlists protect the lane at the proxy boundary.
Relay can now request or approve staging-to-prod promotion, reuse the staged image, and queue rollback when the target lane fails health after the handoff.
There is still no percentage-based split or weighted routing controller in the current implementation.
Use blue-green wording for the current Relay rollout system.
Use session-pinned standby checks when you need to verify the new slot before the old one drains away.
Do not call it canary unless you also explain that there is no weighted traffic split today.
User accounts with RBAC mean deploy access can be scoped to specific people, not shared tokens.
Lane access policies mean dev and staging can require a Relay session before the app is ever served.
Signed-link lanes let teams share temporary access without opening the whole lane publicly.
AES-256-GCM encryption at rest means a leaked database file does not expose secrets.
The audit log means you can answer "who deployed this?", "who requested promotion?", and "who changed that secret?" without digging through logs.
Docker is the default runtime again. Plugin install and remove are disabled by default, and Station should be treated as an intentional exception.