# paseo-relay **_[汉语](./README.zh.md)_** Self-hosted Paseo relay. This repository packages the upstream [`getpaseo/paseo`](https://github.com/getpaseo/paseo) `@getpaseo/relay/cloudflare` adapter as a thin deployment wrapper. It does not implement a custom relay protocol, admin API, or auth layer. The runtime contract stays aligned with upstream Paseo while this repo owns deployment, validation, and operational packaging. ## What This Repo Provides - A minimal Worker entrypoint that re-exports the upstream relay worker and `RelayDurableObject` - Durable Object wiring through Wrangler - Local validation with Bun, TypeScript, Vitest, and Wrangler dry-runs - An OCI image that runs the bundled Worker on `workerd` - GitHub Actions for PR validation, `main` branch deploys, and OCI publishing ## Runtime Contract The public runtime surface is intentionally small: - `GET /health` returns `200` with `{"status":"ok"}` - `GET /ws?...` handles relay and WebSocket traffic This repo does not add any repo-specific API endpoints. ## Quick Start ### Prerequisites - Bun `1.3.12` - Docker, if you want to build or run the OCI image - A Cloudflare account, if you want to deploy the Worker ### Install ```bash bun install ``` ### Run validation ```bash bun run check ``` This runs: - Worker type generation - TypeScript checks - Vitest Worker tests - Generated type drift checks - `wrangler deploy --dry-run` ### Local Worker development ```bash bun run dev ``` ### Build and run the OCI image ```bash bun run oci:build bun run oci:run ``` The OCI image exposes the relay on port `8080`. ### Run the prebuilt OCI image Prebuilt images are published to GHCR: ```bash docker pull ghcr.io/xixu-me/paseo-relay:main docker run --rm -p 8080:8080 -v paseo-relay-data:/var/lib/paseo-relay/do ghcr.io/xixu-me/paseo-relay:main ``` ## Cloudflare Deployment `wrangler.jsonc` is the source of truth for the Worker deployment: - entrypoint: `src/index.ts` - Durable Object binding: `RELAY` - Durable Object class: `RelayDurableObject` - SQLite-backed Durable Object migration: `v1` Deploy with: ```bash bun run deploy ``` > [!NOTE] > `workers.dev` is useful for initial verification, but the intended production path is a custom domain. ## Connecting a Paseo Daemon Paseo expects relay endpoints in `host:port` form. > [!WARNING] > Do not use `https://relay.example.com` here. Use `relay.example.com:443`. Example: ```bash export PASEO_RELAY_ENDPOINT="relay.example.com:443" export PASEO_RELAY_PUBLIC_ENDPOINT="relay.example.com:443" ``` - `PASEO_RELAY_ENDPOINT` is the address the daemon connects to - `PASEO_RELAY_PUBLIC_ENDPOINT` is the address embedded into pairing links and QR codes ## Testing The Worker test suite covers: - `/health` returns `200` - unknown paths return `404` - missing `serverId` returns `400` - invalid relay version returns `400` - non-WebSocket relay requests are rejected - valid WebSocket upgrade requests succeed The OCI validation path additionally checks: - container startup - `/health` over HTTP - a v2 WebSocket upgrade smoke test against the containerized runtime ## CI/CD The repository uses four workflows: - `validate-reusable.yml`: the single validation source of truth - `ci.yml`: runs validation for pull requests and merge groups - `release.yml`: validates, then deploys from `main` and publishes the OCI image - `auto-merge.yml`: enables auto-merge only for Dependabot PRs labeled `dependencies` ### Release behavior - pushes to `main` that change release-relevant files run validation, then deploy the Worker and publish `ghcr.io/xixu-me/paseo-relay:main` - manual `workflow_dispatch` runs can selectively deploy the Worker and/or publish the OCI image ### Required secrets Worker deployment requires: - `CLOUDFLARE_API_TOKEN` - `CLOUDFLARE_ACCOUNT_ID` OCI publishing uses the built-in `GITHUB_TOKEN`. ## OCI Notes The image is built from the Worker bundle generated by Wrangler and served by `workerd`. Prebuilt images are published as `ghcr.io/xixu-me/paseo-relay:main`. The runtime image: - listens on `:8080` - persists Durable Object state under `/var/lib/paseo-relay/do` - runs as a non-root user ## Design Goals - Stay as close as possible to the upstream Paseo relay architecture - Keep repository-owned logic limited to deployment, validation, and packaging - Make Worker and OCI paths testable through the same contract