Skip to content

Services

This content is for the 1.0 version. Switch to the latest version for up-to-date documentation.

This page covers what runs on a single StreamHub node: the six Docker Compose services, why they share the host’s network namespace, the ports involved, and the resource caps that keep one runaway session from taking down the box.

network_mode: host

is set on every media-facing service (redis, livekit, ingress, egress, core, caddy). LiveKit (the SFU), ingress (RTMP/WHIP) and egress (recording) push real-time media over UDP/RTMP and rely on STUN external-IP detection to advertise the right address to clients. Running them on the host network — rather than Docker’s bridge network with port mapping — is the reliable, LiveKit-recommended setup and mirrors a bare-metal deployment. Every service talks to the others over 127.0.0.1, and Caddy (also host-net) terminates TLS on :80/:443.

Service Image What it does Depends on
redis redis:7-alpine LiveKit ingress/egress coordination and BullMQ job queues used by core. Persists with --appendonly yes.
livekit livekit/livekit-server:v1.8.4 The SFU: WebRTC signaling and media fan-out. Config is passed as a literal YAML block via LIVEKIT_CONFIG (note: LIVEKIT_CONFIG, not *_CONFIG_BODY like ingress/egress). redis
ingress livekit/ingress:latest Accepts RTMP push and WHIP, transcodes, and publishes into a LiveKit room. Also the entry point an RTSP→RTMP relay targets. redis, livekit
egress livekit/egress:latest Room-composite recording: runs a headless Chrome per session to produce MP4/HLS on disk. The heaviest service — roughly one Chrome process per active recording or HLS session. redis, livekit
core built from deploy/Dockerfile streamhub-core: REST API, React SPA, HLS, browser SDK, Prometheus /metrics. Binds 127.0.0.1:3020. redis, livekit
caddy caddy:2-alpine Single TLS vhost; routes /rtc to LiveKit and everything else to core. Waits for core’s healthcheck before starting. core (healthy)
Port Proto Purpose Exposure
80, 443 tcp Caddy: dashboard, API, /rtc signaling, auto-TLS public
7880 tcp LiveKit signaling/API public (proxied at /rtc)
7881 tcp LiveKit WebRTC TCP fallback (ICE/TCP) public
7882 udp LiveKit WebRTC media — single mux port public
1935 tcp Ingress: RTMP ingest public
8080 tcp Ingress: WHIP ingest public
3478 udp Embedded TURN (optional; enable with domain + cert) public
3020 tcp streamhub-core local only (proxy target)
6379 tcp redis local only
6789 tcp LiveKit native Prometheus local (scraped by Prometheus)
6790 tcp Ingress native Prometheus local
6791 tcp Egress native Prometheus local
9090 tcp Ingress HTTP relay (internal) local

Each LiveKit-family service needs its own Prometheus port (6789/6790/6791) because they all share the host network namespace — two processes can’t bind the same port.

Ingress and egress transcode and composite media, which makes them the services most likely to consume unbounded CPU/RAM under a bad session. Both are capped via Compose v2’s non-swarm mem_limit/cpus keys, tunable through .env:

Service Default cap Why
ingress mem_limit: 1g, cpus: 1.5 (INGRESS_MEM_LIMIT / INGRESS_CPUS) Transcodes RTMP/WHIP; bounds a runaway publishing session.
egress mem_limit: 2g, cpus: 2 (EGRESS_MEM_LIMIT / EGRESS_CPUS), plus shm_size: 1gb and cap_add: [SYS_ADMIN] Runs a headless Chrome to composite each room; Chrome’s sandbox needs SYS_ADMIN and shared memory. RAM can balloon under multi-track/high-res rooms — this is the single biggest OOM risk on a small host. Defaults target an 8GB/8-core box; raise for heavier rooms.

Egress also mounts the same DATA_DIR path as core (${STREAMHUB_HOST_DATA_DIR:-./data} on the host):

Two supported shapes, same architecture underneath:

  1. Docker Compose + Caddy (default, quick-install) — redis, livekit, ingress, egress, core, caddy as shown above. docker compose up -d; Caddy gets certs automatically. Requires a Linux host with a public IP (host networking for UDP media + STUN).
  2. systemd + nginx + certbot (plain-server) — LiveKit and core run as systemd units, ingress/egress stay as Docker containers, redis runs natively, nginx + certbot handle TLS. This is what the production host (stream01) runs.

Both shapes route the same way (see Overview) and share the same core image — only the process supervisor and TLS termination differ.