Live view over WebRTC (openpanel L1, server and browser)
A device reporting a `live` port streams its camera to the browser's own
RTCPeerConnection. The flows socket carries the signalling as text, so it
crosses the portal: `live` messages on a person's socket, `signal` on a
device's (start, sdp, candidate, bye, busy). The server routes by session,
holds a device to two viewers, ends a session when either socket closes or
no answer comes within 10 s, and gives each socket an outbox of its own
that ends a session rather than drop a message. TURN credentials are
minted per session in coturn's REST scheme (STUN_URLS, TURN_URLS,
TURN_SECRET), the viewer's with the device's offer; GET /devices/{id}/ice
hands them out too. The tunnel keeps a stream's early frames instead of
dropping them past eight and forgets them when the stream or link goes.
A media tile on a device's camera, and the Devices tab's preview, play
live when tapped, pause frames meanwhile, and fall back to frames with a
short note on busy, failure or no picture within 10 s. coturn is an
optional compose service behind the `turn` profile.
This commit is contained in:
@@ -226,6 +226,57 @@ services:
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
|
||||
# ── TURN relay for live view (optional) ────────────────────────────
|
||||
# coturn, for a camera's live view between a viewer and a device that
|
||||
# cannot reach each other directly. It serves STUN too. Behind the `turn`
|
||||
# profile, so a plain `make up` never starts it. On the host's network,
|
||||
# because a relay port range through Docker's port mapping is a proxy
|
||||
# process per port. Credentials are minted by the backend from the same
|
||||
# TURN_SECRET (coturn's REST scheme), so nothing is stored here. The secret
|
||||
# goes in through a config file rather than the command line, which `ps`
|
||||
# shows. See DEPLOY.md for ports, DNS and certificates.
|
||||
coturn:
|
||||
image: coturn/coturn:4.6.3
|
||||
container_name: fluksio-coturn
|
||||
profiles: ["turn"]
|
||||
restart: always
|
||||
network_mode: host
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
environment:
|
||||
# Not `?`: compose reads every service, so a stack without the
|
||||
# profile would refuse to start. Checked when coturn starts instead.
|
||||
- TURN_SECRET=${TURN_SECRET:-}
|
||||
- TURN_REALM=turn.${DOMAIN?Variable not set}
|
||||
- TURN_MIN_PORT=${TURN_MIN_PORT:-49160}
|
||||
- TURN_MAX_PORT=${TURN_MAX_PORT:-49200}
|
||||
volumes:
|
||||
# fullchain.pem and privkey.pem for turn.${DOMAIN}. Without them coturn
|
||||
# runs without TLS on 5349.
|
||||
- ${TURN_CERT_DIR:-./turn-certs}:/certs:ro
|
||||
entrypoint: ["sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
[ -n "$$TURN_SECRET" ] || { echo "TURN_SECRET is empty" >&2; exit 1; }
|
||||
cat > /tmp/turnserver.conf <<EOF
|
||||
static-auth-secret=$$TURN_SECRET
|
||||
EOF
|
||||
exec turnserver -c /tmp/turnserver.conf --log-file=stdout --no-cli \
|
||||
--listening-port=3478 --tls-listening-port=5349 \
|
||||
--min-port=$$TURN_MIN_PORT --max-port=$$TURN_MAX_PORT \
|
||||
--use-auth-secret --realm=$$TURN_REALM --fingerprint \
|
||||
--cert=/certs/fullchain.pem --pkey=/certs/privkey.pem \
|
||||
--no-multicast-peers \
|
||||
--denied-peer-ip=0.0.0.0-0.255.255.255 \
|
||||
--denied-peer-ip=10.0.0.0-10.255.255.255 \
|
||||
--denied-peer-ip=100.64.0.0-100.127.255.255 \
|
||||
--denied-peer-ip=127.0.0.0-127.255.255.255 \
|
||||
--denied-peer-ip=169.254.0.0-169.254.255.255 \
|
||||
--denied-peer-ip=172.16.0.0-172.31.255.255 \
|
||||
--denied-peer-ip=192.168.0.0-192.168.255.255 \
|
||||
--denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff \
|
||||
--denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
|
||||
# ── Site analytics (optional) ──────────────────────────────────────
|
||||
# Self-hosted, cookieless Umami on analytics.${DOMAIN}. Gated behind the
|
||||
# `analytics` profile, so a plain `make up` never starts it; bring it up with
|
||||
|
||||
Reference in New Issue
Block a user