Ports & firewall
This content is for the 1.0 version. Switch to the latest version for up-to-date documentation.
StreamHub’s Docker Compose services run with network_mode: host (Linux-only) — LiveKit,
ingress and egress push real-time media over UDP/RTMP and need STUN external-IP detection, so
host networking mirrors the recommended bare-metal LiveKit setup. Every service talks to the
others over 127.0.0.1; Caddy or nginx (also host-net) terminates TLS on :80/:443.
Port reference
Section titled “Port reference”| Port | Proto | Service | Exposure | Purpose |
|---|---|---|---|---|
80, 443 |
tcp | Caddy / nginx | Public | TLS termination for the dashboard, REST API, HLS, SDK, and LiveKit signaling (/rtc) — everything rides one domain. |
7880 |
tcp (ws) | LiveKit | Public | LiveKit signaling/API. Reached directly by clients, or proxied under /rtc on :443. |
7881 |
tcp | LiveKit | Public | RTC TCP fallback, for clients/networks where the UDP media path is blocked. |
7882 |
udp | LiveKit | Public | WebRTC media — single UDP mux port for all publishers/subscribers on the node. |
1935 |
tcp | Ingress | Public | RTMP publish (OBS, encoders, RTMP push). |
8080 |
tcp | Ingress | Public | WHIP publish. |
9090 |
tcp | Ingress | Internal (loopback, host-net) | http_relay_port — ingress-internal relay, not meant to be reached from outside the host. |
3020 |
tcp | core (NestJS) | Loopback only | REST API /api/v1, dashboard SPA, HLS, SDK, /metrics. Fronted by Caddy/nginx — never expose directly. |
6379 |
tcp | Redis | Loopback / private only | LiveKit ingress/egress coordination + BullMQ queues. Only bind a private (non-public) IP here if serving edge nodes, and password-protect it (REDIS_PASSWORD). |
6789 |
tcp | LiveKit (native) | Loopback only | Prometheus metrics for livekit-server. |
6790 |
tcp | Ingress (native) | Loopback only | Prometheus metrics for ingress. |
6791 |
tcp | Egress (native) | Loopback only | Prometheus metrics for egress. |
These three Prometheus ports are set directly in docker-compose.yml (prometheus_port in
each service’s config body) — they are not environment-tunable. Scrape them locally
(127.0.0.1:678x) and keep them off the public firewall.
Firewall rules
Section titled “Firewall rules”install.sh opens exactly the public-facing set via ufw when it’s active, and never opens
3020 or 6379:
Origin node (full stack: dashboard, API, LiveKit, ingress, egress):
ufw allow 80/tcpufw allow 443/tcpufw allow 1935/tcp # RTMPufw allow 7880/tcp # LiveKit signalingufw allow 7881/tcp # RTC TCP fallbackufw allow 8080/tcp # WHIPufw allow 7882/udp # WebRTC mediaEdge/media node (install.sh --join — no dashboard, no public :80/:443):
ufw allow 1935/tcpufw allow 7880/tcpufw allow 7881/tcpufw allow 8080/tcpufw allow 7882/udpSTREAMHUB_DOMAIN’s A record must point at the server’s public IP DNS-only — do not
proxy it through Cloudflare or a similar CDN in front of the origin. WebRTC media is UDP and
won’t traverse an HTTP(S) reverse proxy; TLS termination for :80/:443 is handled by
Caddy/nginx on the box itself via Let’s Encrypt.
Kernel tuning
Section titled “Kernel tuning”install.sh also raises UDP receive/send buffers to 16 MB
(net.core.rmem_max/wmem_max) if they’re below that — LiveKit’s recommended minimum for
WebRTC under load; the 4 MB Linux default drops packets once several publishers/subscribers
saturate the socket.