name: approbotwebcam # ════════════════════════════════════════════════════════════════════════════ # FINALER WebRTC-AUFBAU – go2rtc (Streaming) + Node.js (Viewer/Proxy/API) # ════════════════════════════════════════════════════════════════════════════ # # Portainer: Stack → Web editor → dieses YAML einfügen → Deploy. # Vorher in Portainer → "Environment variables": # APP_PATH = /absoluter/pfad/zum/appRobotWebcam (Code muss dort liegen) # # WICHTIG: Vor jedem Redeploy sicherstellen, dass server.js / public/ / src/ # auf dem Server unter APP_PATH aktuell sind (Synology-Sync abwarten). # # Firewall (Internet): TCP 8444 (Viewer+API+Signaling) · UDP 8555 (WebRTC-Media) # Port 1984 (go2rtc) NICHT nach aussen – läuft nur intern via localhost. # # Zugriff: # Viewer: http://:8444/ # Snapshot (Homing) http://:8444/api/snapshot/cam0 # go2rtc-Debug-UI http://:1984/ (nur intern/LAN) # ════════════════════════════════════════════════════════════════════════════ configs: go2rtc_yaml: # Komplette go2rtc-Config eingebettet – keine separate Datei nötig. content: | streams: # MJPEG-Passthrough: Kamera → go2rtc → Browser, kein Encoding. # video_size = Aufnahme-Auflösung = Snapshot-Auflösung. # Browser zeigt 640x480 (CSS), Snapshot liefert volle video_size. # Kamera-Maximalauflösung prüfen: v4l2-ctl --list-formats-ext -d /dev/video0 # Gängige Werte: 640x480 / 1280x720 / 1280x960 / 1920x1080 cam0: "ffmpeg:device?video=/dev/video0&input_format=mjpeg&video_size=1280x960&framerate=15#video=mjpeg" cam1: "ffmpeg:device?video=/dev/video2&input_format=mjpeg&video_size=1280x960&framerate=15#video=mjpeg" # Falls 1280x960 nicht unterstützt → 1280x720 versuchen, dann 640x480. # Framerate auf 15fps reduziert da hi-res MJPEG mehr USB-Bandbreite braucht. webrtc: listen: ":8555" candidates: # stun:8555 → go2rtc erkennt die öffentliche IP automatisch (für Internet). # Falls das nicht klappt: feste IP/Domain eintragen, z.B. # - robot.example.com:8555 - stun:8555 api: listen: ":1984" # origin "*" erlaubt das WebSocket-Signaling vom Viewer (Port 8444 = anderer Origin). # Ohne diese Zeile blockt go2rtc den WS mit "request origin not allowed". # LAN: unkritisch. Internet: Caddy davor schränkt den Zugriff wieder ein. origin: "*" log: level: info # On-demand bestätigt: go2rtc startet Encoder erst bei erstem Client (0% CPU ohne Client). services: # ── go2rtc: Kamera-Capture · H.264-Encoding · WebRTC ────────────────────── go2rtc: image: ghcr.io/alexxit/go2rtc container_name: AppRobotGo2RTC restart: unless-stopped network_mode: host # echte Host-IP als WebRTC-ICE-Kandidat devices: - /dev/video0:/dev/video0 - /dev/video2:/dev/video2 # /dev/dri nicht mehr nötig: MJPEG-Passthrough braucht keine GPU group_add: - video # render-Gruppe NICHT hier setzen — existiert im Container-Image nicht → 500-Fehler. # /dev/dri-Zugriff funktioniert via devices: + Container läuft als root. configs: - source: go2rtc_yaml target: /config/go2rtc.yaml # ── webcam: Node.js (Viewer · /api/ws-Proxy · Snapshot-API) ────────────── webcam: build: context: /tmp # Leerer Build-Context – Code kommt per Bind-Mount dockerfile_inline: | FROM node:lts-bookworm-slim WORKDIR /usr/src/app EXPOSE 8444 image: approbotwebcam:latest container_name: AppRobotWebcam restart: unless-stopped network_mode: host # erreicht go2rtc via localhost:1984 command: sh -c "npm install --omit=dev && node server.js" volumes: - ${APP_PATH:-.}:/usr/src/app environment: - NODE_ENV=production - PORT=8444 - GO2RTC_URL=http://localhost:1984 depends_on: - go2rtc # ── FALLBACK ────────────────────────────────────────────────────────────────── # Meckert Portainer beim Deploy über "configs content" (sehr alte Compose-Version)? # → den configs-Block oben löschen und stattdessen beim go2rtc-Service mounten: # volumes: # - ${APP_PATH:-.}/go2rtc.yaml:/config/go2rtc.yaml:ro # # Bleibt eine Kamera schwarz? → in der Config oben die Quelle ersetzen durch die # simple, bestätigte Form (ohne Auflösung): "ffmpeg:/dev/video0#video=h264#video=mjpeg" # ────────────────────────────────────────────────────────────────────────────────