When you're working on Relayfile itself or want a no-container loop, you can run the pieces directly from source. This path uses the durable-local backend so state survives restarts, a local token issuer, and the relayfile-cli binary for login, seed, tree, and mount.
Start the token issuer
relayauth is the local dev JWT issuer. Start it first:
node docker/relayauth/server.jsRun the server
In another terminal, start the file server with the durable-local backend profile so workspace state persists between runs, pointed at the local issuer's JWKS:
RELAYFILE_BACKEND_PROFILE=durable-local \
RELAYFILE_DATA_DIR=.data \
RELAYAUTH_JWKS_URL=http://127.0.0.1:9091/.well-known/jwks.json \
go run ./cmd/relayfileRELAYFILE_BACKEND_PROFILE=durable-local selects a durable on-disk profile (other values include memory for ephemeral test runs and production/prod for a Postgres-backed deployment). RELAYFILE_DATA_DIR is where the durable profile writes state; it defaults to .relayfile.
Generate a dev token and use the CLI
In a third terminal, generate a workspace-scoped dev token and drive the CLI:
export RELAYFILE_WORKSPACE=ws_demo
export RELAYFILE_TOKEN="$(./scripts/generate-dev-token.sh "$RELAYFILE_WORKSPACE")"
go run ./cmd/relayfile-cli login \
--server http://127.0.0.1:8080 \
--token "$RELAYFILE_TOKEN"
go run ./cmd/relayfile-cli seed "$RELAYFILE_WORKSPACE" ./examples
go run ./cmd/relayfile-cli tree "$RELAYFILE_WORKSPACE" /
go run ./cmd/relayfile-cli mount "$RELAYFILE_WORKSPACE" ./relayfile-mount --oncegenerate-dev-token.sh emits a JWT with workspace_id, agent_name, and aud: ["relayfile"], signed with the dev secret (RELAYFILE_JWT_SECRET, default dev-secret).
The default server address is :8080, so the CLI's --server http://127.0.0.1:8080 matches the server you started above. This differs from the Docker stack, which publishes relayfile on port 9090.
Common local commands
# read remote tree and files without mounting
go run ./cmd/relayfile-cli tree ws_demo /
go run ./cmd/relayfile-cli read ws_demo /docs/welcome.md
# one-shot sync for CI
go run ./cmd/relayfile-cli mount ws_demo ./relayfile-mount --once
# export a workspace
go run ./cmd/relayfile-cli export ws_demo --format tar --output ws_demo.tarmount --once runs a single sync cycle and exits, which is the right shape for CI and tests. Drop --once for a long-running mirror. See the CLI reference for the full command and flag set.
Where state lives
The CLI keeps local config under ~/.relayfile/:
credentials.json— self-hosted/API-key credentials only, mode0600.workspaces.json— local workspace metadata (names, IDs, default).
The mount directory keeps sync state under <local-dir>/.relay/ (state.json, conflicts, dead-letter, denial log). For the full set of environment variables the server, mount, and CLI read, this all maps to the source-backed env reference in the Relayfile repo.