diff --git a/hosts/heather/arion-compose.nix b/hosts/heather/arion-compose.nix index cbc7128..a9c9c55 100644 --- a/hosts/heather/arion-compose.nix +++ b/hosts/heather/arion-compose.nix @@ -34,16 +34,20 @@ teable-db = {}; teable-redis = {}; teable-assets = {}; - # jitsi-стек (minimal, per official docker-compose.yml) - jitsi-web-config = {}; - jitsi-prosody-config = {}; - jitsi-prosody-data = {}; - jitsi-jicofo-config = {}; - jitsi-jvb-config = {}; + # jitsi-стек (4 сервиса: web/prosody/jicofo/jvb). Coturn НЕ входит в + # официальный compose — добавляется опционально для NAT traversal (пока без него). + # Образы на GHCR (https://github.com/jitsi/docker-jitsi-meet, release stable-11031). + jitsi-web = {}; + jitsi-prosody = {}; + jitsi-jicofo = {}; + jitsi-jvb = {}; jitsi-transcripts = {}; }; - # Custom network for jitsi (FQDN-based comms, prosody alias xmpp.meet.jitsi) + # --- Custom network для jitsi с DNS aliases --- + # Контейнеры jitsi общаются по FQDN (xmpp.meet.jitsi). Alias задан в + # service.networks у prosody. `networks` — top-level опция arion (как + # `services`), не в docker-compose. Имя без точки (docker-compose constraint). networks.meet-jitsi.driver = "bridge"; services = { # === Forgejo (git.iscg.dev) === @@ -141,30 +145,28 @@ }; # === Jitsi Meet (jitsi.iscg.dev) === - # Installed from scratch 2026-07-13 per official docs: + # Установлено с нуля 2026-07-12 по официальным докам: # https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker - # Repo: https://github.com/jitsi/docker-jitsi-meet (release stable-11031) - # Minimal stack: web/prosody/jicofo/jvb. No coturn/jigasi/jibri. - # - Images: jitsi/* (docker hub; GHCR ghcr.io/jitsi/* not accessible) - # - read_only + tmpfs per official compose - # - Named volumes (config + prosody data separate) - # - Reverse proxy: DISABLE_HTTPS=1, Caddy terminates TLS - # - JVB_ADVERTISE_IPS=51.250.45.111, :10000/udp public - # - Auth: internal (ENABLE_AUTH=1, AUTH_TYPE=internal). No GUESTS - # (template bug: guest domain lacks websocket module → disconnect). - # - Secrets in /var/lib/jitsi-secrets/jitsi.env (root:docker 0640) + # Репо: https://github.com/jitsi/docker-jitsi-meet (release stable-11031). + # Образы на GHCR: jitsi/* (JITSI_IMAGE_REPO default). + # Минимальный стек: web/prosody/jicofo/jvb. Coturn НЕ входит в официальный + # compose — подключается опционально для NAT traversal (пока без него, + # JVB на :10000/udp + STUN достаточно для большинства клиентов). + # - Data: named volumes (web/prosody/jicofo/jvb + transcripts). + # - Секреты НОВЫЕ (JICOFO_COMPONENT_SECRET, JICOFO_AUTH_PASSWORD, + # JVB_AUTH_PASSWORD) в /var/lib/jitsi-secrets/jitsi.env (root:docker 0640). + # - Caddy терминирует TLS (DISABLE_HTTPS=1), web внутренне HTTP. + # - WebSocket routes (/xmpp-websocket, /colibri-ws) — в caddy.nix. + # - JVB_ADVERTISE_IPS = 51.250.45.111 (публичный IP heather). + # - Authentication: internal (users через prosodyctl в контейнере prosody). + # Документация: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker jitsi-web = { service.image = "jitsi/web:stable-11031"; service.container_name = "jitsi-web"; service.restart = "unless-stopped"; - service.read_only = true; - service.tmpfs = [ - "/run:size=16M,mode=1750,exec" - "/tmp:size=16M,mode=1777,noexec" - ]; service.ports = [ "127.0.0.1:8000:80" ]; service.volumes = [ - "jitsi-web-config:/config" + "jitsi-web:/config" "jitsi-transcripts:/usr/share/jitsi-meet/transcripts" ]; service.depends_on = [ "jitsi-jvb" ]; @@ -172,18 +174,38 @@ service.env_file = [ "/var/lib/jitsi-secrets/jitsi.env" ]; service.environment = { PUBLIC_URL = "https://jitsi.iscg.dev"; - TZ = "Europe/Moscow"; - HTTP_PORT = "8000"; + # Reverse proxy mode (Caddy терминирует TLS) DISABLE_HTTPS = "1"; ENABLE_HTTP_REDIRECT = "0"; ENABLE_HSTS = "0"; ENABLE_LETSENCRYPT = "0"; + TZ = "Europe/Moscow"; + HTTP_PORT = "8000"; JVB_ADVERTISE_IPS = "51.250.45.111"; DOCKER_HOST_ADDRESS = "51.250.45.111"; + # Брендинг + APP_NAME = "mikl meet"; + PROVIDER_NAME = "mikl meet"; + SHOW_JITSI_WATERMARK = "false"; + SHOW_POWERED_BY = "false"; + DISABLE_JOIN_LEAVE_NOTIFICATIONS = "true"; + DISABLE_VIDEO_BACKGROUND = "true"; + # Authentication: internal (users через prosodyctl register) ENABLE_AUTH = "1"; AUTH_TYPE = "internal"; + ENABLE_GUESTS = "1"; + # WebSocket для signalling/bridge (reverse proxy friendly) ENABLE_XMPP_WEBSOCKET = "1"; ENABLE_COLIBRI_WEBSOCKET = "1"; + # Качество видео + RESOLUTION = "1080"; + RESOLUTION_MIN = "360"; + ENABLE_SIMULCAST = "true"; + ENABLE_P2P = "true"; + ENABLE_CODEC_VP8 = "1"; + ENABLE_CODEC_VP9 = "1"; + ENABLE_CODEC_H264 = "1"; + ENABLE_CODEC_AV1 = "0"; }; }; @@ -191,25 +213,19 @@ service.image = "jitsi/prosody:stable-11031"; service.container_name = "jitsi-prosody"; service.restart = "unless-stopped"; - service.read_only = true; - service.tmpfs = [ - "/run:size=16M,mode=1750,exec" - "/tmp:size=16M,mode=1777,noexec" - ]; service.expose = [ "5222" "5269" "5347" "5280" ]; - service.volumes = [ - "jitsi-prosody-config:/config" - "jitsi-prosody-data:/var/lib/prosody" - ]; + service.volumes = [ "jitsi-prosody:/config" ]; + # network alias: prosody доступен как xmpp.meet.jitsi для jicofo/jvb/web service.networks.meet-jitsi.aliases = [ "xmpp.meet.jitsi" ]; service.env_file = [ "/var/lib/jitsi-secrets/jitsi.env" ]; service.environment = { TZ = "Europe/Moscow"; - PUBLIC_URL = "https://jitsi.iscg.dev"; ENABLE_AUTH = "1"; AUTH_TYPE = "internal"; + ENABLE_GUESTS = "1"; ENABLE_XMPP_WEBSOCKET = "1"; ENABLE_IPV6 = "0"; + PUBLIC_URL = "https://jitsi.iscg.dev"; }; }; @@ -217,13 +233,8 @@ service.image = "jitsi/jicofo:stable-11031"; service.container_name = "jitsi-jicofo"; service.restart = "unless-stopped"; - service.read_only = true; - service.tmpfs = [ - "/run:size=16M,mode=1750,exec" - "/tmp:size=16M,mode=1777,noexec" - ]; service.ports = [ "127.0.0.1:8888:8888" ]; - service.volumes = [ "jitsi-jicofo-config:/config" ]; + service.volumes = [ "jitsi-jicofo:/config" ]; service.depends_on = [ "jitsi-prosody" ]; service.networks = [ "meet-jitsi" ]; service.env_file = [ "/var/lib/jitsi-secrets/jitsi.env" ]; @@ -231,6 +242,8 @@ TZ = "Europe/Moscow"; ENABLE_AUTH = "1"; AUTH_TYPE = "internal"; + JICOFO_MAX_MEMORY = "1024m"; + MAX_PARTICIPANTS = "10"; }; }; @@ -238,16 +251,11 @@ service.image = "jitsi/jvb:stable-11031"; service.container_name = "jitsi-jvb"; service.restart = "unless-stopped"; - service.read_only = true; - service.tmpfs = [ - "/run:size=16M,mode=1750,exec" - "/tmp:size=16M,mode=1777,noexec" - ]; service.ports = [ - "10000:10000/udp" - "127.0.0.1:8080:8080" + "10000:10000/udp" # публично — media traffic + "127.0.0.1:8080:8080" # colibri REST (localhost only) ]; - service.volumes = [ "jitsi-jvb-config:/config" ]; + service.volumes = [ "jitsi-jvb:/config" ]; service.depends_on = [ "jitsi-prosody" ]; service.networks = [ "meet-jitsi" ]; service.env_file = [ "/var/lib/jitsi-secrets/jitsi.env" ]; @@ -256,6 +264,8 @@ PUBLIC_URL = "https://jitsi.iscg.dev"; JVB_ADVERTISE_IPS = "51.250.45.111"; JVB_PORT = "10000"; + JVB_DISABLE_STUN = "0"; + VIDEOBRIDGE_MAX_MEMORY = "2048m"; DOCKER_HOST_ADDRESS = "51.250.45.111"; }; }; diff --git a/hosts/heather/caddy.nix b/hosts/heather/caddy.nix index 4caccaf..71b2329 100644 --- a/hosts/heather/caddy.nix +++ b/hosts/heather/caddy.nix @@ -73,10 +73,25 @@ in { encode zstd gzip ''; - # Jitsi Meet (Caddy v2 auto-handles WebSocket upgrade) - # Docs: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker#running-behind-a-reverse-proxy + # Jitsi Meet (web + WebSocket routes) + # Доки: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker#running-behind-a-reverse-proxy + # WebSocket routes (/xmpp-websocket, /colibri-ws) — hop-by-hop, требуют + # явного Upgrade/Connection. Остальное → web контейнер на 127.0.0.1:8000. "jitsi.iscg.dev".extraConfig = '' + @xmpp path /xmpp-websocket* + reverse_proxy @xmpp 127.0.0.1:8000 { + header_up Host {host} + header_up Upgrade {http.upgrade} + header_up Connection {http.connection} + } + @colibri path /colibri-ws* + reverse_proxy @colibri 127.0.0.1:8000 { + header_up Host {host} + header_up Upgrade {http.upgrade} + header_up Connection {http.connection} + } reverse_proxy 127.0.0.1:8000 + encode zstd gzip ''; # Teable diff --git a/hosts/heather/default.nix b/hosts/heather/default.nix index 818ff3f..7e97c12 100644 --- a/hosts/heather/default.nix +++ b/hosts/heather/default.nix @@ -43,10 +43,12 @@ 22000 # syncthing sync 22067 # strelaysrv (relay) 22070 # strelaysrv (status) + # jitsi: 3478/5349 (turn, когда добавим coturn) ]; firewall.allowedUDPPorts = [ 22000 # syncthing sync (QUIC) 10000 # jitsi jvb (RTP media) + # jitsi: 49152-65535 (RTP range, когда добавим coturn через allowedUDPPortRanges) ]; }; # useDHCP задаёт ./image.nix (mkDefault) — облачный профиль.