Crosslink’s signaling nodes are horizontally scalable with Redis. Relay channels are
ephemeral and process-local, with region catalogs and host-side fallback for scale-out.
Crosslink does not publish Docker images or Dockerfiles today. Each service is a plain Node.js CLI (@crosslink/signaling’s crosslink-signaling bin, @crosslink/relay’s crosslink-relay bin) built with npm run build, so it packages into a container however you already build Node services — copy services/signaling (or services/relay) and its built dist/ into a node:20-slim (or similar) base image and run the bin.Both services require a bind before phones can reach them from anywhere but the machine they’re on; use your normal container port-mapping.
Shared secret hosts must present; required unless per-machine dev tokens apply
CROSSLINK_RELAY_CLIENT_TOKEN
(none)
Optional shared secret clients must present to attach
CROSSLINK_RELAY_MAX_CLIENTS
(unset)
Max clients per relay channel
CROSSLINK_RELAY_MAX_CHANNELS
1024
Max allocated channels per process
CROSSLINK_RELAY_MAX_BYTES
(unlimited)
Lifetime traffic cap per channel
CROSSLINK_RELAY_BYTES_PER_SEC
(unlimited)
Token-bucket rate per channel
CROSSLINK_RELAY_PUBLIC_URL
(none)
Public HTTPS URL for this relay region
CROSSLINK_RELAY_REGIONS
(none)
JSON array of regional URLs and priorities
Outside of local development, both services refuse to start without an auth token (CROSSLINK_SIGNALING_TOKEN / CROSSLINK_RELAY_TOKEN) or the per-machine dev tokens written to .crosslink-data/dev-tokens.json. Set these explicitly for any deployment other services will connect to.
Signaling can be horizontally scaled when every replica uses the same Redis
deployment. Relay WebSockets require channel affinity; deploy independent regional
relay pools and let hosts allocate using ordered regional fallback:
upstream signaling { server 10.0.0.1:8081; server 10.0.0.2:8081; server 10.0.0.3:8081;}upstream relay { server 10.0.0.1:8082; server 10.0.0.2:8082; server 10.0.0.3:8082;}
Do not round-robin an allocated relay channel across processes. Either keep
WebSocket affinity for the channel or publish each relay pool as a distinct regional
allocation endpoint.
Relay channel state and signaling presence are ephemeral. Redis persistence is not
required for correctness after a restart, but production configuration must be
recoverable. Back up: