Skip to content

feat(relay-docker): add self-hosted Docker relay deployment and harden runtime reliability#14

Open
HansYeoh wants to merge 2 commits intop697:mainfrom
HansYeoh:feat/add-docker-feature
Open

feat(relay-docker): add self-hosted Docker relay deployment and harden runtime reliability#14
HansYeoh wants to merge 2 commits intop697:mainfrom
HansYeoh:feat/add-docker-feature

Conversation

@HansYeoh
Copy link
Copy Markdown
Contributor

@HansYeoh HansYeoh commented Apr 4, 2026

Summary

This PR introduces a self-hosted Docker deployment for relay services and includes follow-up hardening from review feedback to improve runtime safety, shutdown behavior, and packaging reliability.

Changes

1. Add relay-docker self-hosted stack

  • Added a new relay-docker workspace for self-hosted deployment.
  • Added Dockerfile and docker-compose setup.
  • Added nginx configuration example.
  • Added environment variable example file.
  • Added English and Chinese documentation for setup and usage.
  • Implemented registry and relay runtime components for Docker deployment.

2. Improve websocket and runtime safety

  • Serialized room initialization to prevent concurrent init races.
  • Serialized socket event handling and added stronger error boundaries.
  • Wrapped upgrade handling with explicit try/catch to avoid unhandled failures.
  • Standardized rejection close codes:
    • 4401 for unauthorized
    • 4409 for conflict or capacity-related rejection
    • 4400 for invalid request
  • Added telemetry capture for heartbeat scheduling failures.

3. Improve graceful shutdown

  • Made registry and relay server close logic async and awaitable.
  • Added idempotent, signal-safe shutdown flow for process termination.

4. Improve Docker and package build reliability

  • Removed hardcoded npm mirror behavior in Docker build.
  • Added configurable NPM_REGISTRY build argument.
  • Removed brittle sed-based package patching.
  • Added relay-shared dist package metadata generation script.
  • Added relay-shared build tsconfig for clean distribution output.

5. Add tests and workspace integration

  • Added runtime smoke tests for:
    • health endpoint
    • pairing flow
    • auth rejection close code behavior
    • upgrade error handling path
  • Integrated relay-docker into monorepo relay typecheck and relay test workflows.

Validation

  • npm run relay:typecheck
  • npm run relay:test
  • docker build -f apps/relay-docker/Dockerfile .

Commit Breakdown

  • 51a4324 feat: add relay-docker self-hosted deployment
  • 447f1a4 fix(relay-docker): resolve review findings for docker runtime

Notes for Reviewers

  • This PR intentionally keeps a two-commit structure: one feature commit and one review-fix commit.
  • Existing non-Docker deployment behavior is preserved.

HansYeoh added 2 commits April 4, 2026 13:03
- fix relay-room init race and serialize ws event handling

- harden ws upgrade error handling and close-code mapping

- implement graceful async shutdown for registry/relay servers

- remove Dockerfile hardcoded registry and sed patching

- add relay-shared build artifact packaging and relay-docker smoke tests
Copilot AI review requested due to automatic review settings April 4, 2026 12:47
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new self-hosted Docker deployment option for the relay stack and adjusts shared-package build outputs so the Docker runtime can consume @clawket/shared as compiled ESM with proper dist/package.json metadata.

Changes:

  • Introduces apps/relay-docker (Node HTTP registry + ws relay in one process) with docs, compose/nginx examples, and runtime smoke tests.
  • Adds @clawket/shared build/distribution metadata generation (dist/package.json) and ESM-friendly export specifiers.
  • Wires relay-docker into the root relay typecheck/test workflows.

Reviewed changes

Copilot reviewed 32 out of 33 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/relay-shared/tsconfig.build.json Build tsconfig for producing a clean dist/ output (excludes tests).
packages/relay-shared/src/index.ts Switches to ESM-compatible .js export specifier.
packages/relay-shared/scripts/write-dist-package-json.mjs Generates dist/package.json metadata for runtime consumption.
packages/relay-shared/package.json Adds build script to emit dist/ + generated dist/package.json.
package.json Extends relay typecheck/test scripts to include @clawket/relay-docker.
apps/relay-docker/tsconfig.json TypeScript config for the relay-docker workspace.
apps/relay-docker/tsconfig.build.json Build tsconfig for relay-docker (excludes tests).
apps/relay-docker/src/server.ts Process entrypoint that starts registry + relay servers and handles shutdown.
apps/relay-docker/src/runtime.test.ts Smoke tests for health endpoints, pairing, auth rejection close codes, and upgrade error path.
apps/relay-docker/src/room-manager.ts In-memory room routing/GC for gateway rooms.
apps/relay-docker/src/relay/utils.ts Utility helpers (ported) for runtime parsing.
apps/relay-docker/src/relay/types.ts Relay type definitions/constants for the docker runtime.
apps/relay-docker/src/relay/telemetry.ts Structured telemetry logging with basic field filtering.
apps/relay-docker/src/relay/storage.ts Storage/rehydration helpers adapted for the Node/ws shim.
apps/relay-docker/src/relay/runtime.ts Relay runtime state container for docker rooms.
apps/relay-docker/src/relay/routing.ts Message routing and control-plane forwarding logic.
apps/relay-docker/src/relay/heartbeat.ts Alarm/heartbeat scheduling and pruning logic.
apps/relay-docker/src/relay/frames.ts Frame parsing helpers for connect/control flows.
apps/relay-docker/src/relay/control.ts Control envelope parsing/serialization + gateway replacement.
apps/relay-docker/src/relay/auth.ts Token authorization logic using MemoryKV + optional registry verify.
apps/relay-docker/src/relay-server.ts Node HTTP server + ws upgrade handling for the relay endpoint.
apps/relay-docker/src/relay-room.ts Docker port of RelayRoom: initialization serialization + socket event queueing.
apps/relay-docker/src/registry.ts Node HTTP implementation of pairing/verify registry APIs.
apps/relay-docker/src/kv-store.ts In-memory KV with optional better-sqlite3 persistence + TTL GC.
apps/relay-docker/src/globals.d.ts Ambient type declarations intended to fill gaps for Node global fetch-related types.
apps/relay-docker/src/cf-shim.ts Cloudflare Durable Object API shims (storage, alarms, attachments) for Node.
apps/relay-docker/README.zh-CN.md Chinese documentation for docker deployment usage and caveats.
apps/relay-docker/README.md English documentation for docker deployment usage and caveats.
apps/relay-docker/package.json Workspace manifest and scripts for relay-docker.
apps/relay-docker/nginx.conf.example Example reverse-proxy config for registry + relay endpoints.
apps/relay-docker/Dockerfile Multi-stage build for relay-docker runtime image.
apps/relay-docker/docker-compose.yml Compose file for local/self-hosted deployment.
apps/relay-docker/.env.example Example environment configuration for docker deployment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +565 to +575
const onEnd = (): void => {
try {
finish({ ok: true, data: JSON.parse(Buffer.concat(chunks).toString()) as T });
} catch {
finish({ ok: true, data: null });
}
};

const onError = (): void => {
finish({ ok: true, data: null });
};
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readJsonBodyLimited treats invalid JSON (and request stream errors) as { ok: true, data: null }. For endpoints like POST /v1/pair/register, this means malformed JSON bodies still succeed and create pairing records with default values. Consider returning { ok: false, status: 400, body: { error: { code: 'INVALID_JSON', message: 'Invalid JSON body' }}} when parsing fails (and possibly distinguishing empty body vs malformed body).

Copilot uses AI. Check for mistakes.
@p697 p697 self-assigned this Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants