Deploy a relay
A distributed run needs a relay: CI runners take no inbound connection, so the run and its workers all dial out to it. You host your own. It runs on Cloudflare’s free plan, or on Bun or Docker anywhere your CI can reach.
-
Deploy the relay.
The button copies the relay into a new repository of yours and deploys it. It asks for one var,
ALLOW(step 2). The relay’s URL is the Worker’s, such ashttps://vx-dte-server.<you>.workers.dev.From
packages/vx-dte-serverin a checkout of the vx repository, withALLOWfilled inwrangler.jsonc’svarsfirst:Terminal window bun installbunx wrangler loginbunx wrangler deployFrom a checkout of the vx repository:
Terminal window bun packages/vx-dte-server/src/bun.ts \--allow https://token.actions.githubusercontent.com:acme/app:ci.yml \--allow https://token.actions.githubusercontent.com:acme/app:vx-worker.yml \--audience https://relay.example.com --port 8080--audienceis the relay’s public URL. Put it behind HTTPS.Terminal window docker build -t vx-dte-server packages/vx-dte-serverdocker run -p 8080:8080 vx-dte-server \--allow https://token.actions.githubusercontent.com:acme/app:ci.yml \--allow https://token.actions.githubusercontent.com:acme/app:vx-worker.yml \--audience https://relay.example.com -
Say who may use it:
ALLOW. One entry per workflow,issuer:owner/repo:workflow, space separated. List both the workflow that runsvx runand the workers’ workflow; every other token is refused.wrangler.jsonc "vars": {"ALLOW": "https://token.actions.githubusercontent.com:acme/app:ci.yml https://token.actions.githubusercontent.com:acme/app:vx-worker.yml"}- GitHub Actions:
https://token.actions.githubusercontent.com:acme/app:ci.yml - GitLab:
https://gitlab.com:group/project:.gitlab-ci.yml
On Bun and Docker each entry is one
--allow. GitLab names a project by its full path,group/subgroup/project. - GitHub Actions:
-
Check it answers. A request with no token is refused by name:
Terminal window curl https://relay.example.com/v1/runs/$(uuidgen)/socket{"error":"no bearer token"}A Cloudflare relay with an empty
ALLOWsays so instead:this relay's ALLOW is empty: it admits no run. -
Name it in
dte()..vx/workspace.ts dte({relay: 'https://relay.example.com',workers: { small: { max: 8, cpu: 4, memory: '16GB' } },adapter: github(),})Each side proves itself with its job’s OIDC token for the relay’s URL, so no secret is stored. On GitHub Actions both workflows need
permissions: { id-token: write }; on GitLab the orchestrator and worker jobs ask for one:id_tokens: { VX_DTE_TOKEN: { aud: https://relay.example.com } }.
What to know
Section titled “What to know”- The relay carries orders and status, never files: outputs go through your remote cache.
- On Cloudflare each run is one Durable Object, and the relay fits the
free plan: websocket messages count 20 to one Durable Object request,
against 100,000 a day, and it writes about two rows a worker. A
deploy keeps the runs in flight: each side dials back. On Bun and
Docker runs live in memory unless
--state <file>keeps them, so a restart keeps the runs it was carrying. - The wire is Switchboard v1, an open protocol: any server that speaks it can stand in for this relay.
AUDIENCE(Cloudflare) is unset by default: tokens must name the URL the relay is reached at. Set it only when they name another one.
See @vzn/vx-dte-server
for every option and the API to mount it in a server of your own.