This commit is contained in:
jack ning
2025-10-21 11:47:42 +08:00
parent c50e6eb583
commit 6858e13dcd
130 changed files with 12981 additions and 244 deletions

View File

@@ -425,11 +425,13 @@ sudo ln -s /etc/nginx/sites-available/weiyuai_cn_demo_80.conf /etc/nginx/sites-e
sudo ln -s /etc/nginx/sites-available/weiyuai_cn_demo_443.conf /etc/nginx/sites-enabled/ && \
sudo ln -s /etc/nginx/sites-available/weiyuai_cn_janus_80.conf /etc/nginx/sites-enabled/ && \
sudo ln -s /etc/nginx/sites-available/weiyuai_cn_janus_443.conf /etc/nginx/sites-enabled/ && \
sudo ln -s /etc/nginx/sites-available/weiyuai_cn_jitsi_80.conf /etc/nginx/sites-enabled/ && \
sudo ln -s /etc/nginx/sites-available/weiyuai_cn_jitsi_443.conf /etc/nginx/sites-enabled/ && \
sudo ln -s /etc/nginx/sites-available/weiyuai_cn_sip_80.conf /etc/nginx/sites-enabled/ && \
sudo ln -s /etc/nginx/sites-available/weiyuai_cn_sip_443.conf /etc/nginx/sites-enabled/
# 方法2使用 for 循环(推荐)
for conf in weiyuai_cn_80 weiyuai_cn_443 weiyuai_cn_api_80 weiyuai_cn_api_443 weiyuai_cn_coturn_80.conf weiyuai_cn_coturn_443.conf weiyuai_cn_demo_80 weiyuai_cn_demo_443 weiyuai_cn_sip_80 weiyuai_cn_sip_443; do
for conf in weiyuai_cn_80 weiyuai_cn_443 weiyuai_cn_api_80 weiyuai_cn_api_443 weiyuai_cn_coturn_80.conf weiyuai_cn_coturn_443.conf weiyuai_cn_demo_80 weiyuai_cn_demo_443 weiyuai_cn_janus_80 weiyuai_cn_janus_443 weiyuai_cn_jitsi_80 weiyuai_cn_jitsi_443 weiyuai_cn_sip_80 weiyuai_cn_sip_443; do
sudo ln -s /etc/nginx/sites-available/${conf}.conf /etc/nginx/sites-enabled/
done

View File

@@ -1,8 +1,8 @@
#
# HTTPS server for jitsi.weiyuai.cn - proxy to Jitsi server
# HTTPS server for jitsi.weiyuai.cn - proxy to Jitsi Meet server
server {
listen 443 ssl;
listen [::]:443 ssl;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/weiyuai.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/weiyuai.cn/privkey.pem;
@@ -11,16 +11,16 @@ server {
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Enforce HTTPS on this subdomain
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# jitsi HTTP API
location /jitsi {
proxy_pass http://121.36.247.120:8088;
# Root location - proxy to Jitsi Meet main interface
location / {
proxy_pass http://121.36.247.120:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -30,26 +30,20 @@ server {
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
# CORS headers
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Max-Age 1728000;
add_header Content-Type 'text/plain; charset=utf-8';
add_header Content-Length 0;
return 204;
}
}
# jitsi Admin HTTP API - more specific path first
location /admin/ {
proxy_pass http://121.36.247.120:7088/;
# External API
location /external_api.js {
proxy_pass http://121.36.247.120:80/external_api.js;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# BOSH (HTTP binding for XMPP)
location /http-bind {
proxy_pass http://121.36.247.120:5280/http-bind;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -59,55 +53,28 @@ server {
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
# CORS headers
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Max-Age 1728000;
add_header Content-Type 'text/plain; charset=utf-8';
add_header Content-Length 0;
return 204;
}
}
# jitsi Admin HTTP API - exact path
location = /admin {
proxy_pass http://121.36.247.120:7088;
# WebSocket for XMPP
location /xmpp-websocket {
proxy_pass http://121.36.247.120:5280/xmpp-websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
# CORS headers
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Max-Age 1728000;
add_header Content-Type 'text/plain; charset=utf-8';
add_header Content-Length 0;
return 204;
}
}
# jitsi WebSocket API (both WS and WSS use same backend)
location /jitsi/ {
proxy_pass http://121.36.247.120:8188/;
# Colibri WebSocket (for JVB communication)
location ~ ^/colibri-ws/([a-zA-Z0-9-_.]+)/(.*) {
proxy_pass http://121.36.247.120:9090/colibri-ws/$1/$2;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
@@ -121,84 +88,7 @@ server {
proxy_connect_timeout 60s;
proxy_buffering off;
# CORS headers
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Max-Age 1728000;
add_header Content-Type 'text/plain; charset=utf-8';
add_header Content-Length 0;
return 204;
}
}
# jitsi Admin WebSocket API (port 7188)
location /admin-ws/ {
proxy_pass http://121.36.247.120:7188/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_connect_timeout 60s;
proxy_buffering off;
# CORS headers
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Max-Age 1728000;
add_header Content-Type 'text/plain; charset=utf-8';
add_header Content-Length 0;
return 204;
}
}
# Static file serving for jitsi demos
location /demos {
alias /var/www/html/jitsi;
index index.html index.htm;
# Enable directory listing (optional)
autoindex on;
autoindex_format html;
autoindex_exact_size off;
autoindex_localtime on;
# CORS headers for demos
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Expose-Headers "Content-Length,Content-Range" always;
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://jitsi.weiyuai.cn" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Max-Age 1728000;
add_header Content-Type 'text/plain; charset=utf-8';
add_header Content-Length 0;
return 204;
}
# Try to serve file directly, fallback to index.html
try_files $uri $uri/ /demos/index.html;
tcp_nodelay on;
}
# Health check
@@ -207,106 +97,4 @@ server {
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 默认根路径:返回服务说明页
location / {
default_type text/html;
return 200 '<!DOCTYPE html>
<html>
<head>
<title>jitsi WebRTC Gateway</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Arial, sans-serif;
max-width: 900px;
margin: 50px auto;
padding: 20px;
background: #f5f5f5;
}
.container {
background: #fff;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 { color: #333; }
h2 { color: #666; margin-top: 24px; }
.info {
background: #e3f2fd;
padding: 15px;
border-radius: 6px;
margin: 16px 0;
border-left: 4px solid #2196f3;
}
.warning {
background: #fff3e0;
padding: 15px;
border-radius: 6px;
margin: 16px 0;
border-left: 4px solid #ff9800;
}
code {
background: #f5f5f5;
padding: 2px 6px;
border-radius: 3px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
pre {
background: #263238;
color: #aed581;
padding: 15px;
border-radius: 6px;
overflow-x: auto;
}
a { color: #2196f3; text-decoration: none; }
a:hover { text-decoration: underline; }
ul { line-height: 1.8; }
</style>
</head>
<body>
<div class="container">
<h1>🚪 jitsi WebRTC Gateway</h1>
<div class="warning">
<strong>提示:</strong> 这是反向代理到 jitsi 的 HTTPS 入口。媒体传输使用 UDP/TCP 端口,由 jitsi/插件直接处理,非通过本页面。
</div>
<h2>可用端点</h2>
<div class="info">
<ul>
<li>HTTP API<code>https://jitsi.weiyuai.cn/jitsi</code></li>
<li>Admin API<code>https://jitsi.weiyuai.cn/admin</code></li>
<li>WebSocket API<code>wss://jitsi.weiyuai.cn/jitsi/</code></li>
<li>Admin WebSocket<code>wss://jitsi.weiyuai.cn/admin-ws/</code></li>
<li>Demos<a href="/demos/" target="_blank">/demos/</a></li>
<li>健康检查:<a href="/health" target="_blank">/health</a></li>
</ul>
</div>
<h2>快速测试WebSocket</h2>
<pre>const ws = new WebSocket("wss://jitsi.weiyuai.cn/jitsi/");
ws.onopen = () => {
// 发送创建会话请求示例实际需生成唯一事务ID
ws.send(JSON.stringify({
jitsi: "create",
transaction: "tx-123456"
}));
};
ws.onmessage = (evt) => console.log("jitsi:", evt.data);
ws.onerror = (e) => console.error("WS error", e);
</pre>
<h2>参考</h2>
<ul>
<li><a href="https://jitsi.conf.jitsiecho.com/" target="_blank">jitsi 官方站点</a></li>
<li><a href="https://github.com/jitsiecho/jitsi-gateway" target="_blank">GitHub - jitsi-gateway</a></li>
<li><a href="/demos/" target="_blank">本机 Demos 集合</a></li>
</ul>
</div>
</body>
</html>';
}
}

View File

@@ -0,0 +1,154 @@
name: CI Test Build
on:
pull_request:
push:
branches:
- master
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Check Node / npm versions
run: |
node -v
npm -v
- name: setup tpl
run: |
dpkgArch="$(dpkg --print-architecture)"
case "${dpkgArch##*-}" in \
"amd64") TPL_ARCH=amd64; S6_ARCH=amd64 ;; \
"arm64") TPL_ARCH=arm64; S6_ARCH=aarch64 ;; \
*) echo "unsupported architecture"; exit 1 ;; \
esac
wget -qO /tmp/tpl https://github.com/jitsi/tpl/releases/latest/download/tpl-linux-${TPL_ARCH}
chmod +x /tmp/tpl
- name: setup duktape
working-directory: /tmp
run: |
wget https://duktape.org/duktape-2.2.1.tar.xz
tar xvf duktape-2.2.1.tar.xz
cd duktape-2.2.1
make -f Makefile.cmdline
mv duk /usr/local/bin
- name: Run tpl with default values for web
env:
P2P_STUN_SERVERS: stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302
run: |
/tmp/tpl web/rootfs/defaults/system-config.js > /tmp/config.js
/tmp/tpl web/rootfs/defaults/settings-config.js >> /tmp/config.js
echo "console.log(JSON.stringify(config, undefined, 2));" >> /tmp/config.js
cat /tmp/config.js
- name: Check config.js syntax
run: duk /tmp/config.js
- name: Run tpl with default values for jvb
run: |
/tmp/tpl jvb/rootfs/defaults/jvb.conf > /tmp/jvb.conf
/tmp/tpl jvb/rootfs/defaults/logging.properties > /tmp/logging.properties
/tmp/tpl jvb/rootfs/defaults/autoscaler-sidecar.config > /tmp/autoscaler-sidecar.config
- name: Run tpl with default values for jicofo
run: |
/tmp/tpl jicofo/rootfs/defaults/jicofo.conf > /tmp/jicofo.conf
/tmp/tpl jicofo/rootfs/defaults/logging.properties > /tmp/logging.properties
- name: Run tpl with default values for jibri
run: |
/tmp/tpl jibri/rootfs/defaults/jibri.conf > /tmp/jibri.conf
/tmp/tpl jibri/rootfs/defaults/logging.properties > /tmp/logging.properties
/tmp/tpl jibri/rootfs/defaults/xmpp.conf > /tmp/xmpp.conf
/tmp/tpl jibri/rootfs/defaults/xorg-video-dummy.conf > /tmp/xorg-video-dummy.conf
/tmp/tpl jibri/rootfs/defaults/autoscaler-sidecar.config > /tmp/autoscaler-sidecar.config
- name: Run tpl with default values for jigasi
run: |
/tmp/tpl jigasi/rootfs/defaults/sip-communicator.properties > /tmp/sip-communicator.properties
/tmp/tpl jigasi/rootfs/defaults/sipserver-sip-communicator.properties > /tmp/xmpp-sip-communicator.properties
/tmp/tpl jigasi/rootfs/defaults/transcriber-sip-communicator.properties > /tmp/xmpp-sip-communicator.properties
/tmp/tpl jigasi/rootfs/defaults/xmpp-sip-communicator.properties > /tmp/xmpp-sip-communicator.properties
/tmp/tpl jigasi/rootfs/defaults/logging.properties > /tmp/logging.properties
/tmp/tpl jigasi/rootfs/defaults/autoscaler-sidecar.config > /tmp/autoscaler-sidecar.config
- name: Run tpl with default values for prosody
run: |
/tmp/tpl prosody/rootfs/defaults/prosody.cfg.lua > /tmp/prosody.cfg.lua
/tmp/tpl prosody/rootfs/defaults/saslauthd.conf > /tmp/saslauthd.conf
/tmp/tpl prosody/rootfs/defaults/conf.d/jitsi-meet.cfg.lua > /tmp/jitsi-meet.cfg.lua
/tmp/tpl prosody/rootfs/defaults/conf.d/brewery.cfg.lua > /tmp/brewery.cfg.lua
/tmp/tpl prosody/rootfs/defaults/conf.d/visitors.cfg.lua > /tmp/visitors.cfg.lua
/tmp/tpl prosody/rootfs/defaults/rules.d/jvb_muc_presence_filter.pfw > /tmp/jvb_muc_presence_filter.pfw
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Build base
uses: docker/build-push-action@v6
with:
context: ./base
load: true
tags: |
jitsi/base:latest
build-args: |
JITSI_RELEASE=unstable
- name: Build base-java
uses: docker/build-push-action@v6
with:
context: ./base-java
load: true
tags: |
jitsi/base-java:latest
- name: Build jibri
uses: docker/build-push-action@v6
with:
context: ./jibri
load: true
tags: |
jitsi/jibri:latest
- name: Build jicofo
uses: docker/build-push-action@v6
with:
context: ./jicofo
load: true
tags: |
jitsi/jicofo:latest
- name: Build jigasi
uses: docker/build-push-action@v6
with:
context: ./jigasi
load: true
tags: |
jitsi/jigasi:latest
- name: Build jvb
uses: docker/build-push-action@v6
with:
context: ./jvb
load: true
tags: |
jitsi/jvb:latest
- name: Build prosody
uses: docker/build-push-action@v6
with:
context: ./prosody
load: true
tags: |
jitsi/prosody:latest
- name: Build web
uses: docker/build-push-action@v6
with:
context: ./web
load: true
tags: |
jitsi/web:latest

View File

@@ -0,0 +1,288 @@
name: "Release Stable"
on:
workflow_dispatch:
inputs:
version:
description: Version number
required: true
type: string
jobs:
gh-release:
runs-on: ubuntu-latest
needs: [base, base-java, jibri, jicofo, jigasi, jvb, prosody, web]
permissions:
# Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository.
contents: write
steps:
- uses: actions/checkout@v4
- run: |
sed -i".bak" -e "s/unstable/stable-${{ github.event.inputs.version }}/" *.yml
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "release: stable-${{ github.event.inputs.version }}"
- name: release
uses: softprops/action-gh-release@v2
with:
tag_name: stable-${{ github.event.inputs.version }}
generate_release_notes: true
make_latest: true
- run: |
sed -i".bak" -e "s/stable-${{ github.event.inputs.version }}/unstable/" *.yml
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "misc: working on unstable"
base:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./base
tags: |
${{ secrets.JITSI_REPO }}/base:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/base:stable
build-args: |
JITSI_RELEASE=stable
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
base-java:
runs-on: ubuntu-latest
needs: base
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./base-java
tags: |
${{ secrets.JITSI_REPO }}/base-java:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/base-java:stable
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=stable-${{ github.event.inputs.version }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
jibri:
runs-on: ubuntu-latest
needs: base-java
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jibri
tags: |
${{ secrets.JITSI_REPO }}/jibri:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/jibri:stable
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=stable-${{ github.event.inputs.version }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
jicofo:
runs-on: ubuntu-latest
needs: base-java
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jicofo
tags: |
${{ secrets.JITSI_REPO }}/jicofo:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/jicofo:stable
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=stable-${{ github.event.inputs.version }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
jigasi:
runs-on: ubuntu-latest
needs: base-java
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jigasi
tags: |
${{ secrets.JITSI_REPO }}/jigasi:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/jigasi:stable
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=stable-${{ github.event.inputs.version }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
jvb:
runs-on: ubuntu-latest
needs: base-java
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jvb
tags: |
${{ secrets.JITSI_REPO }}/jvb:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/jvb:stable
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=stable-${{ github.event.inputs.version }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
prosody:
runs-on: ubuntu-latest
needs: base
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./prosody
tags: |
${{ secrets.JITSI_REPO }}/prosody:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/prosody:stable
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=stable-${{ github.event.inputs.version }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
web:
runs-on: ubuntu-latest
needs: base
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./web
tags: |
${{ secrets.JITSI_REPO }}/web:stable-${{ github.event.inputs.version }}
${{ secrets.JITSI_REPO }}/web:stable
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=stable-${{ github.event.inputs.version }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -0,0 +1,21 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-issue-label: 'stale'
stale-pr-label: 'stale'
exempt-issue-labels: 'confirmed'
exempt-pr-labels: 'confirmed'
days-before-issue-stale: 60
days-before-pr-stale: 90
days-before-issue-close: 10
days-before-pr-close: 10

View File

@@ -0,0 +1,482 @@
name: Unstable Build
on:
schedule:
- cron: "0 5 * * *"
workflow_dispatch:
jobs:
version:
runs-on: ubuntu-latest
outputs:
base: unstable
date: unstable-${{ steps.date.outputs.date }}
prosody_version: prosody-${{ steps.prosody_version.outputs.version }}
jicofo_version: jicofo-${{ steps.jicofo_version.outputs.version }}
web_version: web-${{ steps.web_version.outputs.version }}
jvb_version: jvb-${{ steps.jvb_version.outputs.version }}
jibri_version: jibri-${{ steps.jibri_version.outputs.version }}
jigasi_version: jigasi-${{ steps.jigasi_version.outputs.version }}
steps:
- name: Get current date
id: date
run: echo "date=$(date +%F)">> $GITHUB_OUTPUT
- name: Prosody gpg key
id: prosody_gpg_key
run: curl --location --silent --show-error https://prosody.im/files/prosody-debian-packages.key | sudo dd of=/etc/apt/keyrings/prosody.gpg
- name: Prosody dsa1024 key support
run: echo 'APT::Key::Assert-Pubkey-Algo ">=rsa2048,ed25519,ed448,dsa1024";' | sudo tee /etc/apt/apt.conf.d/99weakkey-warning
- name: Prosody repo
id: prosody_repo
run: echo "deb [signed-by=/etc/apt/keyrings/prosody.gpg] https://packages.prosody.im/debian bookworm main" | sudo tee /etc/apt/sources.list.d/prosody.list
- name: Jitsi repo
uses: myci-actions/add-deb-repo@11
with:
repo: deb https://download.jitsi.org/ unstable/
repo-name: jitsi
keys-asc: https://download.jitsi.org/jitsi-key.gpg.key
- name: Get current jicofo versions
id: jicofo_version
run: echo "version=$( apt-cache show jitsi-meet | head -10 | grep '^Depends:' | tr ',' '\n' | grep jicofo | cut -d'=' -f2 | tr -d ')' | awk '{print $1}' )" >> $GITHUB_OUTPUT
- name: Get current jitsi-meet-web versions
id: web_version
run: echo "version=$( apt-cache show jitsi-meet | head -10 | grep '^Depends:' | tr ',' '\n' | grep 'jitsi-meet-web ' | cut -d'=' -f2 | tr -d ')' | awk '{print $1}' )" >> $GITHUB_OUTPUT
- name: Get current jvb versions
id: jvb_version
run: echo "version=$( apt-cache show jitsi-meet | head -10 | grep '^Pre-Depends:'| tr ',' '\n' | grep 'jitsi-videobridge2' | cut -d'=' -f2 | tr -d ')' | awk '{print $1}' )" >> $GITHUB_OUTPUT
- name: Get current prosody versions
id: prosody_version
run: echo "version=$( apt-cache madison prosody | awk '{print $3;}' | head -1 | cut -d'-' -f1 )" >> $GITHUB_OUTPUT
- name: Get current jibri version
id: jibri_version
run: echo "version=$( apt-cache show jibri | head -10 | grep Version | awk '{print $2}' )" >> $GITHUB_OUTPUT
- name: Get current jigasi version
id: jigasi_version
run: echo "version=$( apt-cache show jigasi | head -10 | grep Version | awk '{print $2}' )" >> $GITHUB_OUTPUT
base-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: version
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./base
tags: |
${{ secrets.JITSI_REPO }}/base:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/base:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
build-args: |
JITSI_RELEASE=unstable
base:
runs-on: ubuntu-latest
needs: [version, base-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/base:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/base:${{ needs.version.outputs.date }}
sources: |
${{ secrets.JITSI_REPO }}/base:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/base:${{ needs.version.outputs.base }}-arm64
base-java-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: [version, base]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./base-java
tags: |
${{ secrets.JITSI_REPO }}/base-java:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/base-java:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=${{ needs.version.outputs.base }}
base-java:
runs-on: ubuntu-latest
needs: [version, base-java-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/base-java:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/base-java:${{ needs.version.outputs.date }}
sources: |
${{ secrets.JITSI_REPO }}/base-java:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/base-java:${{ needs.version.outputs.base }}-arm64
jibri-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: [version, base-java]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jibri
tags: |
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.jibri_version }}-${{ matrix.config.arch }}
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=${{ needs.version.outputs.base }}
jibri:
runs-on: ubuntu-latest
needs: [version, jibri-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.date }}
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.jibri_version }}
sources: |
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/jibri:${{ needs.version.outputs.base }}-arm64
jicofo-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: [version, base-java]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jicofo
tags: |
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.jicofo_version }}-${{ matrix.config.arch }}
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=${{ needs.version.outputs.base }}
jicofo:
runs-on: ubuntu-latest
needs: [version, jicofo-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.date }}
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.jicofo_version }}
sources: |
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/jicofo:${{ needs.version.outputs.base }}-arm64
jigasi-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: [version, base-java]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jigasi
tags: |
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.jigasi_version }}-${{ matrix.config.arch }}
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=${{ needs.version.outputs.base }}
jigasi:
runs-on: ubuntu-latest
needs: [version, jigasi-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.date }}
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.jigasi_version }}
sources: |
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/jigasi:${{ needs.version.outputs.base }}-arm64
jvb-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: [version, base-java]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./jvb
tags: |
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.jvb_version }}-${{ matrix.config.arch }}
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=${{ needs.version.outputs.base }}
jvb:
runs-on: ubuntu-latest
needs: [version, jvb-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.date }}
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.jvb_version }}
sources: |
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/jvb:${{ needs.version.outputs.base }}-arm64
prosody-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: [version, base]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./prosody
tags: |
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.prosody_version }}-${{ matrix.config.arch }}
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=${{ needs.version.outputs.base }}
prosody:
runs-on: ubuntu-latest
needs: [version, prosody-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.date }}
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.prosody_version }}
sources: |
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/prosody:${{ needs.version.outputs.base }}-arm64
web-arch:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, arch: amd64 }
- { os: ubuntu-24.04-arm, arch: arm64 }
needs: [version, base]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
context: ./web
tags: |
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.base }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.date }}-${{ matrix.config.arch }}
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.web_version }}-${{ matrix.config.arch }}
build-args: |
JITSI_REPO=${{ secrets.JITSI_REPO }}
BASE_TAG=${{ needs.version.outputs.base }}
web:
runs-on: ubuntu-latest
needs: [version, web-arch]
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create Docker Manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.base }}
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.date }}
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.web_version }}
sources: |
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.base }}-amd64
${{ secrets.JITSI_REPO }}/web:${{ needs.version.outputs.base }}-arm64

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,63 @@
FORCE_REBUILD ?= 0
JITSI_RELEASE ?= stable
JITSI_BUILD ?= unstable
JITSI_REPO ?= jitsi
JITSI_SERVICES := base base-java web prosody jicofo jvb jigasi jibri
BUILD_ARGS := \
--build-arg JITSI_REPO=$(JITSI_REPO) \
--build-arg JITSI_RELEASE=$(JITSI_RELEASE)
ifeq ($(FORCE_REBUILD), 1)
BUILD_ARGS := $(BUILD_ARGS) --no-cache
endif
all: build-all
release:
@$(foreach SERVICE, $(JITSI_SERVICES), $(MAKE) --no-print-directory JITSI_SERVICE=$(SERVICE) buildx;)
buildx:
docker buildx build \
--platform linux/amd64,linux/arm64 \
--progress=plain \
$(BUILD_ARGS) --build-arg BASE_TAG=$(JITSI_BUILD) \
--pull --push \
--tag $(JITSI_REPO)/$(JITSI_SERVICE):$(JITSI_BUILD) \
--tag $(JITSI_REPO)/$(JITSI_SERVICE):$(JITSI_RELEASE) \
$(JITSI_SERVICE)
$(addprefix buildx_,$(JITSI_SERVICES)):
$(MAKE) --no-print-directory JITSI_SERVICE=$(patsubst buildx_%,%,$@) buildx
build:
docker buildx build \
$(BUILD_ARGS) \
--load \
--progress plain \
--tag $(JITSI_REPO)/$(JITSI_SERVICE) \
$(JITSI_SERVICE)
$(addprefix build_,$(JITSI_SERVICES)):
$(MAKE) --no-print-directory JITSI_SERVICE=$(patsubst build_%,%,$@) build
tag:
docker tag $(JITSI_REPO)/$(JITSI_SERVICE) $(JITSI_REPO)/$(JITSI_SERVICE):$(JITSI_BUILD)
push:
docker push $(JITSI_REPO)/$(JITSI_SERVICE):$(JITSI_BUILD)
%-all:
@$(foreach SERVICE, $(JITSI_SERVICES), $(MAKE) --no-print-directory JITSI_SERVICE=$(SERVICE) $(subst -all,;,$@))
clean:
docker-compose stop
docker-compose rm
docker network prune
prepare:
FORCE_REBUILD=1 $(MAKE)
.PHONY: all build tag push clean prepare release $(addprefix build_,$(JITSI_SERVICES))

View File

@@ -0,0 +1,39 @@
# Jitsi Meet on Docker
![](resources/jitsi-docker.png)
[Jitsi](https://jitsi.org/) is a set of Open Source projects that allows you to easily build and deploy secure videoconferencing solutions.
[Jitsi Meet](https://jitsi.org/jitsi-meet/) is a fully encrypted, 100% Open Source video conferencing solution that you can use all day, every day, for free — with no account needed.
This repository contains the necessary tools to run a Jitsi Meet stack on [Docker](https://www.docker.com) using [Docker Compose](https://docs.docker.com/compose/).
All our images are published on [DockerHub](https://hub.docker.com/u/jitsi/).
## Supported architectures
Starting with `stable-7439` the published images are available for `amd64` and `arm64`.
## Tags
These are the currently published tags for all our images:
Tag | Description
-- | --
`stable` | Points to the latest stable release
`stable-NNNN-X` | A stable release
`unstable` | Points to the latest unstable release
`unstable-YYYY-MM-DD` | Daily unstable release
`latest` | Deprecated, no longer updated (will be removed)
## Installation
The installation manual is available [here](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker).
### Kubernetes
If you plan to install the jitsi-meet stack on a Kubernetes cluster you can find tools and tutorials in the project [Jitsi on Kubernetes](https://github.com/jitsi-contrib/jitsi-kubernetes).
## TODO
* Builtin TURN server.

View File

@@ -0,0 +1,18 @@
# Jitsi
- [参考文档](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker)
```bash
# 切换目录
cd jitsi-docker
# 复制
cp env.example .env
# 生成密码
./gen-passwords.sh
# 创建目录
mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
# 打开目录
open ~/.jitsi-meet-cfg
# 运行
docker compose up -d
```

View File

@@ -0,0 +1,13 @@
ARG JITSI_REPO=jitsi
ARG BASE_TAG=latest
FROM ${JITSI_REPO}/base:${BASE_TAG}
RUN mkdir -p /usr/share/man/man1 && \
mkdir -p /etc/apt/keyrings/ && \
apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y unzip ca-certificates curl gnupg && \
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y nodejs openjdk-17-jre-headless openjdk-17-jdk-headless && \
apt-cleanup

View File

@@ -0,0 +1,40 @@
FROM docker.io/library/debian:bookworm-slim
ARG JITSI_RELEASE=stable
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2
COPY rootfs /
RUN \
dpkgArch="$(dpkg --print-architecture)" && \
case "${dpkgArch##*-}" in \
"amd64") TPL_ARCH=amd64; S6_ARCH=amd64 ;; \
"arm64") TPL_ARCH=arm64; S6_ARCH=aarch64 ;; \
*) echo "unsupported architecture"; exit 1 ;; \
esac && \
apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y apt-transport-https apt-utils ca-certificates gnupg wget curl && \
wget -qO /usr/bin/tpl https://github.com/jitsi/tpl/releases/download/v1.4.0/tpl-linux-${TPL_ARCH} && \
# Workaround S6 bug when /bin is a symlink
wget -qO /tmp/s6.tar.gz https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-${S6_ARCH}.tar.gz && \
mkdir /tmp/s6 && \
tar xfz /tmp/s6.tar.gz -C /tmp/s6 && \
tar hxfz /tmp/s6.tar.gz -C / && \
rm -f /usr/bin/execlineb && \
cp /tmp/s6/bin/execlineb /usr/bin/ && \
rm -rf /tmp/s6* && \
wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | gpg --dearmour > /etc/apt/trusted.gpg.d/jitsi.gpg && \
echo "deb https://download.jitsi.org $JITSI_RELEASE/" > /etc/apt/sources.list.d/jitsi.list && \
echo "deb http://ftp.debian.org/debian bookworm-backports main" > /etc/apt/sources.list.d/backports.list && \
apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get dist-upgrade -y && \
apt-cleanup && \
chmod +x /usr/bin/tpl
RUN [ "$JITSI_RELEASE" = "unstable" ] && \
apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y jq procps curl vim iputils-ping net-tools && \
apt-cleanup || \
true
ENTRYPOINT [ "/init" ]

View File

@@ -0,0 +1,2 @@
APT::Install-Recommends "false";
APT::Install-Suggests "false";

View File

@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash
if [[ ! -z "$TZ" ]]; then
if [[ -f /usr/share/zoneinfo/$TZ ]]; then
ln -sf /usr/share/zoneinfo/$TZ /etc/localtime
echo "$TZ" > /etc/timezone
else
echo "WARNING: $TZ is not a valid time zone."
fi
fi

View File

@@ -0,0 +1,3 @@
#!/bin/sh
rm -rf /var/lib/apt/lists/

View File

@@ -0,0 +1,8 @@
#!/bin/sh
export LC_ALL=C
export DEBIAN_FRONTEND=noninteractive
bin=$1
shift
exec "$bin" "$@"

View File

@@ -0,0 +1,509 @@
services:
# Frontend
web:
image: jitsi/web:${JITSI_IMAGE_VERSION:-stable-10590}
restart: ${RESTART_POLICY:-unless-stopped}
ports:
- '${HTTP_PORT}:80'
- '${HTTPS_PORT}:443'
volumes:
- ${CONFIG}/web:/config:Z
- ${CONFIG}/web/crontabs:/var/spool/cron/crontabs:Z
- ${CONFIG}/transcripts:/usr/share/jitsi-meet/transcripts:Z
- ${CONFIG}/web/load-test:/usr/share/jitsi-meet/load-test:Z
labels:
service: "jitsi-web"
environment:
- AMPLITUDE_ID
- ANALYTICS_SCRIPT_URLS
- ANALYTICS_WHITELISTED_EVENTS
- AUDIO_QUALITY_OPUS_BITRATE
- AUTO_CAPTION_ON_RECORD
- BRANDING_DATA_URL
- BWE_ESTIMATOR_ENGINE
- BOSH_RELATIVE
- CHROME_EXTENSION_BANNER_JSON
- CODEC_ORDER_JVB
- CODEC_ORDER_JVB_MOBILE
- CODEC_ORDER_P2P
- CODEC_ORDER_P2P_MOBILE
- COLIBRI_WEBSOCKET_PORT
- COLIBRI_WEBSOCKET_JVB_LOOKUP_NAME
- COLIBRI_WEBSOCKET_REGEX
- CONFCODE_URL
- CORS_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN
- DEFAULT_LANGUAGE
- DEPLOYMENTINFO_ENVIRONMENT
- DEPLOYMENTINFO_ENVIRONMENT_TYPE
- DEPLOYMENTINFO_REGION
- DEPLOYMENTINFO_SHARD
- DESKTOP_SHARING_FRAMERATE_AUTO
- DESKTOP_SHARING_FRAMERATE_MIN
- DESKTOP_SHARING_FRAMERATE_MAX
- DIALIN_NUMBERS_URL
- DIALOUT_AUTH_URL
- DIALOUT_CODES_URL
- DISABLE_AUDIO_LEVELS
- DISABLE_COLIBRI_WEBSOCKET_JVB_LOOKUP
- DISABLE_DEEP_LINKING
- DISABLE_GRANT_MODERATOR
- DISABLE_HTTPS
- DISABLE_KICKOUT
- DISABLE_LOCAL_RECORDING
- DISABLE_POLLS
- DISABLE_PRIVATE_CHAT
- DISABLE_PROFILE
- DISABLE_REACTIONS
- DISABLE_REMOTE_VIDEO_MENU
- DISABLE_START_FOR_ALL
- DROPBOX_APPKEY
- DROPBOX_REDIRECT_URI
- DYNAMIC_BRANDING_URL
- ENABLE_ADAPTIVE_MODE
- ENABLE_AUDIO_PROCESSING
- ENABLE_AUTOMATIC_GAIN_CONTROL
- ENABLE_AUTH
- ENABLE_AUTH_DOMAIN
- ENABLE_BREAKOUT_ROOMS
- ENABLE_CALENDAR
- ENABLE_COLIBRI_WEBSOCKET
- ENABLE_COLIBRI_WEBSOCKET_UNSAFE_REGEX
- ENABLE_E2EPING
- ENABLE_FILE_RECORDING_SHARING
- ENABLE_GUESTS
- ENABLE_HSTS
- ENABLE_HTTP_REDIRECT
- ENABLE_IPV6
- ENABLE_LETSENCRYPT
- ENABLE_NO_AUDIO_DETECTION
- ENABLE_NOISY_MIC_DETECTION
- ENABLE_OCTO
- ENABLE_OPUS_RED
- ENABLE_PREJOIN_PAGE
- ENABLE_P2P
- ENABLE_WELCOME_PAGE
- ENABLE_CLOSE_PAGE
- ENABLE_LIVESTREAMING
- ENABLE_LIVESTREAMING_DATA_PRIVACY_LINK
- ENABLE_LIVESTREAMING_HELP_LINK
- ENABLE_LIVESTREAMING_TERMS_LINK
- ENABLE_LIVESTREAMING_VALIDATOR_REGEXP_STRING
- ENABLE_LOAD_TEST_CLIENT
- ENABLE_LOCAL_RECORDING_NOTIFY_ALL_PARTICIPANT
- ENABLE_LOCAL_RECORDING_SELF_START
- ENABLE_RECORDING
- ENABLE_REMB
- ENABLE_REQUIRE_DISPLAY_NAME
- ENABLE_SERVICE_RECORDING
- ENABLE_SIMULCAST
- ENABLE_STATS_ID
- ENABLE_STEREO
- ENABLE_SUBDOMAINS
- ENABLE_TALK_WHILE_MUTED
- ENABLE_TCC
- ENABLE_TRANSCRIPTIONS
- ENABLE_VLA
- ENABLE_XMPP_WEBSOCKET
- ENABLE_JAAS_COMPONENTS
- ETHERPAD_PUBLIC_URL
- ETHERPAD_URL_BASE
- E2EPING_NUM_REQUESTS
- E2EPING_MAX_CONFERENCE_SIZE
- E2EPING_MAX_MESSAGE_PER_SECOND
- GOOGLE_ANALYTICS_ID
- GOOGLE_API_APP_CLIENT_ID
- HIDE_PREMEETING_BUTTONS
- HIDE_PREJOIN_DISPLAY_NAME
- HIDE_PREJOIN_EXTRA_BUTTONS
- INVITE_SERVICE_URL
- JVB_PREFER_SCTP
- LETSENCRYPT_DOMAIN
- LETSENCRYPT_EMAIL
- LETSENCRYPT_USE_STAGING
- LETSENCRYPT_ACME_SERVER
- MATOMO_ENDPOINT
- MATOMO_SITE_ID
- MICROSOFT_API_APP_CLIENT_ID
- NGINX_KEEPALIVE_TIMEOUT
- NGINX_RESOLVER
- NGINX_WORKER_PROCESSES
- NGINX_WORKER_CONNECTIONS
- PEOPLE_SEARCH_URL
- PREFERRED_LANGUAGE
- PUBLIC_URL
- P2P_PREFERRED_CODEC
- P2P_STUN_SERVERS
- RESOLUTION
- RESOLUTION_MIN
- RESOLUTION_WIDTH
- RESOLUTION_WIDTH_MIN
- START_AUDIO_MUTED
- START_AUDIO_ONLY
- START_SILENT
- START_WITH_AUDIO_MUTED
- START_VIDEO_MUTED
- START_WITH_VIDEO_MUTED
- TOKEN_AUTH_URL
- TOOLBAR_BUTTONS
- TRANSLATION_LANGUAGES
- TRANSLATION_LANGUAGES_HEAD
- TZ
- USE_APP_LANGUAGE
- VIDEOQUALITY_BITRATE_H264_LOW
- VIDEOQUALITY_BITRATE_H264_STANDARD
- VIDEOQUALITY_BITRATE_H264_HIGH
- VIDEOQUALITY_BITRATE_H264_FULL
- VIDEOQUALITY_BITRATE_H264_ULTRA
- VIDEOQUALITY_BITRATE_H264_SS_HIGH
- VIDEOQUALITY_BITRATE_VP8_LOW
- VIDEOQUALITY_BITRATE_VP8_STANDARD
- VIDEOQUALITY_BITRATE_VP8_HIGH
- VIDEOQUALITY_BITRATE_VP8_FULL
- VIDEOQUALITY_BITRATE_VP8_ULTRA
- VIDEOQUALITY_BITRATE_VP8_SS_HIGH
- VIDEOQUALITY_BITRATE_VP9_LOW
- VIDEOQUALITY_BITRATE_VP9_STANDARD
- VIDEOQUALITY_BITRATE_VP9_HIGH
- VIDEOQUALITY_BITRATE_VP9_FULL
- VIDEOQUALITY_BITRATE_VP9_ULTRA
- VIDEOQUALITY_BITRATE_VP9_SS_HIGH
- VIDEOQUALITY_BITRATE_AV1_LOW
- VIDEOQUALITY_BITRATE_AV1_STANDARD
- VIDEOQUALITY_BITRATE_AV1_HIGH
- VIDEOQUALITY_BITRATE_AV1_FULL
- VIDEOQUALITY_BITRATE_AV1_ULTRA
- VIDEOQUALITY_BITRATE_AV1_SS_HIGH
- VIDEOQUALITY_PREFERRED_CODEC
- XMPP_AUTH_DOMAIN
- XMPP_BOSH_URL_BASE
- XMPP_DOMAIN
- XMPP_GUEST_DOMAIN
- XMPP_MUC_DOMAIN
- XMPP_HIDDEN_DOMAIN
- XMPP_PORT
- XMPP_RECORDER_DOMAIN
- WHITEBOARD_COLLAB_SERVER_PUBLIC_URL
- WHITEBOARD_COLLAB_SERVER_URL_BASE
networks:
meet.jitsi:
depends_on:
- jvb
# XMPP server
prosody:
image: jitsi/prosody:${JITSI_IMAGE_VERSION:-stable-10590}
restart: ${RESTART_POLICY:-unless-stopped}
expose:
- '${XMPP_PORT:-5222}'
- '${PROSODY_S2S_PORT:-5269}'
- '5347'
- '${PROSODY_HTTP_PORT:-5280}'
labels:
service: "jitsi-prosody"
volumes:
- ${CONFIG}/prosody/config:/config:Z
- ${CONFIG}/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z
environment:
- AUTH_TYPE
- DISABLE_POLLS
- ENABLE_AUTH
- ENABLE_AV_MODERATION
- ENABLE_BREAKOUT_ROOMS
- ENABLE_END_CONFERENCE
- ENABLE_GUESTS
- ENABLE_IPV6
- ENABLE_LOBBY
- ENABLE_RECORDING
- ENABLE_S2S
- ENABLE_TRANSCRIPTIONS
- ENABLE_VISITORS
- ENABLE_XMPP_WEBSOCKET
- ENABLE_JAAS_COMPONENTS
- GC_TYPE
- GC_INC_TH
- GC_INC_SPEED
- GC_INC_STEP_SIZE
- GC_GEN_MIN_TH
- GC_GEN_MAX_TH
- GLOBAL_CONFIG
- GLOBAL_MODULES
- JIBRI_RECORDER_USER
- JIBRI_RECORDER_PASSWORD
- JIBRI_SIP_BREWERY_MUC
- JIBRI_XMPP_USER
- JIBRI_XMPP_PASSWORD
- JICOFO_AUTH_PASSWORD
- JICOFO_COMPONENT_SECRET
- JIGASI_TRANSCRIBER_PASSWORD
- JIGASI_TRANSCRIBER_USER
- JIGASI_XMPP_USER
- JIGASI_XMPP_PASSWORD
- JVB_AUTH_USER
- JVB_AUTH_PASSWORD
- JWT_APP_ID
- JWT_APP_SECRET
- JWT_ACCEPTED_ISSUERS
- JWT_ACCEPTED_AUDIENCES
- JWT_ASAP_KEYSERVER
- JWT_ALLOW_EMPTY
- JWT_AUTH_TYPE
- JWT_ENABLE_DOMAIN_VERIFICATION
- JWT_SIGN_TYPE
- JWT_TOKEN_AUTH_MODULE
- MATRIX_UVS_URL
- MATRIX_UVS_ISSUER
- MATRIX_UVS_AUTH_TOKEN
- MATRIX_UVS_SYNC_POWER_LEVELS
- MATRIX_LOBBY_BYPASS
- LOG_LEVEL
- LDAP_AUTH_METHOD
- LDAP_BASE
- LDAP_BINDDN
- LDAP_BINDPW
- LDAP_FILTER
- LDAP_VERSION
- LDAP_TLS_CIPHERS
- LDAP_TLS_CHECK_PEER
- LDAP_TLS_CACERT_FILE
- LDAP_TLS_CACERT_DIR
- LDAP_START_TLS
- LDAP_URL
- LDAP_USE_TLS
- MAX_PARTICIPANTS
- PROSODY_ADMINS
- PROSODY_AUTH_TYPE
- PROSODY_C2S_LIMIT
- PROSODY_C2S_REQUIRE_ENCRYPTION
- PROSODY_RESERVATION_ENABLED
- PROSODY_RESERVATION_REST_BASE_URL
- PROSODY_DISABLE_C2S_LIMIT
- PROSODY_DISABLE_S2S_LIMIT
- PROSODY_ENABLE_FILTER_MESSAGES
- PROSODY_ENABLE_RATE_LIMITS
- PROSODY_ENABLE_RECORDING_METADATA
- PROSODY_ENABLE_STANZA_COUNTS
- PROSODY_ENABLE_S2S
- PROSODY_ENABLE_METRICS
- PROSODY_GUEST_AUTH_TYPE
- PROSODY_HTTP_PORT
- PROSODY_LOG_CONFIG
- PROSODY_METRICS_ALLOWED_CIDR
- PROSODY_MODE
- PROSODY_RATE_LIMIT_LOGIN_RATE
- PROSODY_RATE_LIMIT_SESSION_RATE
- PROSODY_RATE_LIMIT_TIMEOUT
- PROSODY_RATE_LIMIT_ALLOW_RANGES
- PROSODY_RATE_LIMIT_CACHE_SIZE
- PROSODY_S2S_LIMIT
- PROSODY_S2S_PORT
- PROSODY_TRUSTED_PROXIES
- PROSODY_VISITOR_INDEX
- PROSODY_VISITORS_MUC_PREFIX
- PROSODY_VISITORS_S2S_VHOSTS
- PUBLIC_URL
- STUN_HOST
- STUN_PORT
- TURN_CREDENTIALS
- TURN_USERNAME
- TURN_PASSWORD
- TURN_HOST
- TURNS_HOST
- TURN_PORT
- TURNS_PORT
- TURN_TRANSPORT
- TURN_TTL
- TZ
- VISITORS_MAX_VISITORS_PER_NODE
- VISITORS_XMPP_DOMAIN
- VISITORS_XMPP_SERVER
- VISITORS_XMPP_PORT
- XMPP_BREAKOUT_MUC_MODULES
- XMPP_CONFIGURATION
- XMPP_DOMAIN
- XMPP_AUTH_DOMAIN
- XMPP_GUEST_DOMAIN
- XMPP_MUC_DOMAIN
- XMPP_INTERNAL_MUC_DOMAIN
- XMPP_LOBBY_MUC_MODULES
- XMPP_MODULES
- XMPP_MUC_MODULES
- XMPP_MUC_CONFIGURATION
- XMPP_INTERNAL_MUC_MODULES
- XMPP_HIDDEN_DOMAIN
- XMPP_PORT
- XMPP_RECORDER_DOMAIN
- XMPP_SERVER_S2S_PORT
- XMPP_SPEAKERSTATS_MODULES
networks:
meet.jitsi:
aliases:
- ${XMPP_SERVER:-xmpp.meet.jitsi}
# Focus component
jicofo:
image: jitsi/jicofo:${JITSI_IMAGE_VERSION:-stable-10590}
restart: ${RESTART_POLICY:-unless-stopped}
ports:
- '127.0.0.1:${JICOFO_REST_PORT:-8888}:8888'
volumes:
- ${CONFIG}/jicofo:/config:Z
labels:
service: "jitsi-jicofo"
environment:
- AUTH_TYPE
- BRIDGE_AVG_PARTICIPANT_STRESS
- BRIDGE_STRESS_THRESHOLD
- ENABLE_AUTH
- ENABLE_AUTO_OWNER
- ENABLE_MODERATOR_CHECKS
- ENABLE_CODEC_VP8
- ENABLE_CODEC_VP9
- ENABLE_CODEC_AV1
- ENABLE_CODEC_H264
- ENABLE_CODEC_OPUS_RED
- ENABLE_JVB_XMPP_SERVER
- ENABLE_OCTO
- ENABLE_OCTO_SCTP
- ENABLE_RECORDING
- ENABLE_SCTP
- ENABLE_SHARED_DOCUMENT_RANDOM_NAME
- ENABLE_TRANSCRIPTIONS
- ENABLE_VISITORS
- ENABLE_AUTO_LOGIN
- JICOFO_AUTH_LIFETIME
- JICOFO_AUTH_PASSWORD
- JICOFO_AUTH_TYPE
- JICOFO_BRIDGE_REGION_GROUPS
- JICOFO_ENABLE_AUTH
- JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS
- JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT
- JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT
- JICOFO_CONF_SOURCE_SIGNALING_DELAYS
- JICOFO_CONF_MAX_AUDIO_SENDERS
- JICOFO_CONF_MAX_VIDEO_SENDERS
- JICOFO_CONF_STRIP_SIMULCAST
- JICOFO_CONF_SSRC_REWRITING
- JICOFO_ENABLE_HEALTH_CHECKS
- JICOFO_ENABLE_ICE_FAILURE_DETECTION
- JICOFO_ENABLE_LOAD_REDISTRIBUTION
- JICOFO_ENABLE_REST
- JICOFO_HEALTH_CHECKS_USE_PRESENCE
- JICOFO_ICE_FAILURE_INTERVAL
- JICOFO_ICE_FAILURE_MIN_ENDPOINTS
- JICOFO_ICE_FAILURE_THRESHOLD
- JICOFO_MAX_MEMORY
- JICOFO_MULTI_STREAM_BACKWARD_COMPAT
- JICOFO_OCTO_REGION
- JICOFO_RESTART_REQUEST_MAX
- JICOFO_RESTART_REQUEST_INTERVAL
- JICOFO_TRUSTED_DOMAINS
- JIBRI_BREWERY_MUC
- JIBRI_REQUEST_RETRIES
- JIBRI_PENDING_TIMEOUT
- JIGASI_BREWERY_MUC
- JIGASI_SIP_URI
- JIGASI_TRUSTED_DOMAINS
- JVB_BREWERY_MUC
- JVB_XMPP_AUTH_DOMAIN
- JVB_XMPP_INTERNAL_MUC_DOMAIN
- JVB_XMPP_PORT
- JVB_XMPP_SERVER
- MAX_BRIDGE_PARTICIPANTS
- OCTO_BRIDGE_SELECTION_STRATEGY
- PROSODY_VISITORS_MUC_PREFIX
- SENTRY_DSN="${JICOFO_SENTRY_DSN:-0}"
- SENTRY_ENVIRONMENT
- SENTRY_RELEASE
- TZ
- VISITORS_MAX_PARTICIPANTS
- VISITORS_MAX_VISITORS_PER_NODE
- VISITORS_XMPP_AUTH_DOMAIN
- VISITORS_XMPP_SERVER
- VISITORS_XMPP_DOMAIN
- XMPP_DOMAIN
- XMPP_AUTH_DOMAIN
- XMPP_INTERNAL_MUC_DOMAIN
- XMPP_MUC_DOMAIN
- XMPP_HIDDEN_DOMAIN
- XMPP_SERVER
- XMPP_PORT
- XMPP_RECORDER_DOMAIN
- MAX_SSRCS_PER_USER
- MAX_SSRC_GROUPS_PER_USER
depends_on:
- prosody
networks:
meet.jitsi:
# Video bridge
jvb:
image: jitsi/jvb:${JITSI_IMAGE_VERSION:-stable-10590}
restart: ${RESTART_POLICY:-unless-stopped}
ports:
- '${JVB_PORT:-10000}:${JVB_PORT:-10000}/udp'
- '127.0.0.1:${JVB_COLIBRI_PORT:-8080}:8080'
volumes:
- ${CONFIG}/jvb:/config:Z
labels:
service: "jitsi-jvb"
environment:
- AUTOSCALER_SIDECAR_KEY_FILE
- AUTOSCALER_SIDECAR_KEY_ID
- AUTOSCALER_SIDECAR_GROUP_NAME
- AUTOSCALER_SIDECAR_HOST_ID
- AUTOSCALER_SIDECAR_INSTANCE_ID
- AUTOSCALER_SIDECAR_PORT
- AUTOSCALER_SIDECAR_REGION
- AUTOSCALER_SIDECAR_SHUTDOWN_POLLING_INTERVAL
- AUTOSCALER_SIDECAR_STATS_POLLING_INTERVAL
- DISABLE_AWS_HARVESTER
- DOCKER_HOST_ADDRESS
- ENABLE_COLIBRI_WEBSOCKET
- ENABLE_JVB_XMPP_SERVER
- ENABLE_OCTO
- ENABLE_SCTP
- JVB_ADVERTISE_IPS
- JVB_ADVERTISE_PRIVATE_CANDIDATES
- JVB_AUTH_USER
- JVB_AUTH_PASSWORD
- JVB_BREWERY_MUC
- JVB_CC_TRUST_BWE
- JVB_DISABLE_STUN
- JVB_DISABLE_XMPP
- JVB_INSTANCE_ID
- JVB_PORT
- JVB_MUC_NICKNAME
- JVB_STUN_SERVERS
- JVB_LOG_FILE
- JVB_OCTO_BIND_ADDRESS
- JVB_OCTO_REGION
- JVB_OCTO_RELAY_ID
- JVB_REQUIRE_VALID_ADDRESS
- JVB_USE_USRSCTP
- JVB_WS_DOMAIN
- JVB_WS_SERVER_ID
- JVB_WS_TLS
- JVB_XMPP_AUTH_DOMAIN
- JVB_XMPP_INTERNAL_MUC_DOMAIN
- JVB_XMPP_PORT
- JVB_XMPP_SERVER
- PUBLIC_URL
- SENTRY_DSN="${JVB_SENTRY_DSN:-0}"
- SENTRY_ENVIRONMENT
- SENTRY_RELEASE
- COLIBRI_REST_ENABLED
- SHUTDOWN_REST_ENABLED
- TZ
- VIDEOBRIDGE_MAX_MEMORY
- XMPP_AUTH_DOMAIN
- XMPP_INTERNAL_MUC_DOMAIN
- XMPP_SERVER
- XMPP_PORT
depends_on:
- prosody
networks:
meet.jitsi:
# Custom network so all services can communicate using a FQDN
networks:
meet.jitsi:

View File

@@ -0,0 +1,227 @@
# shellcheck disable=SC2034
################################################################################
################################################################################
# Welcome to the Jitsi Meet Docker setup!
#
# This sample .env file contains some basic options to get you started.
# The full options reference can be found here:
# https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker
################################################################################
################################################################################
#
# Basic configuration options
#
# Directory where all configuration will be stored
CONFIG=~/.jitsi-meet-cfg
# Exposed HTTP port (will redirect to HTTPS port)
HTTP_PORT=8000
# Exposed HTTPS port
HTTPS_PORT=8443
# System time zone
TZ=UTC
# Public URL for the web service (required)
# Keep in mind that if you use a non-standard HTTPS port, it has to appear in the public URL
#PUBLIC_URL=https://meet.example.com:${HTTPS_PORT}
# Media IP addresses and ports to advertise by the JVB
# This setting deprecates DOCKER_HOST_ADDRESS, and supports a comma separated list of IPs
# See the "Running behind NAT or on a LAN environment" section in the Handbook:
# https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker#running-behind-nat-or-on-a-lan-environment
#JVB_ADVERTISE_IPS=192.168.1.1,1.2.3.4,192.168.178.1#12000,fe80::1#12000
#
# Memory limits for Java components
#
#JICOFO_MAX_MEMORY=3072m
#VIDEOBRIDGE_MAX_MEMORY=3072m
#
# JaaS Components (beta)
# https://jaas.8x8.vc
#
# Enable JaaS Components (hosted Jigasi)
# NOTE: if Let's Encrypt is enabled a JaaS account will be automatically created, using the provided email in LETSENCRYPT_EMAIL
#ENABLE_JAAS_COMPONENTS=0
#
# Let's Encrypt configuration
#
# Enable Let's Encrypt certificate generation
#ENABLE_LETSENCRYPT=1
# Domain for which to generate the certificate
#LETSENCRYPT_DOMAIN=meet.example.com
# E-Mail for receiving important account notifications (mandatory)
#LETSENCRYPT_EMAIL=alice@atlanta.net
# Use the staging server (for avoiding rate limits while testing)
#LETSENCRYPT_USE_STAGING=1
# Set ACME server. Default is zerossl, you can peek one at https://github.com/acmesh-official/acme.sh/wiki/Server
#LETSENCRYPT_ACME_SERVER="letsencrypt"
#
# Etherpad integration (for document sharing)
#
# Set the etherpad-lite URL in the docker local network (uncomment to enable)
#ETHERPAD_URL_BASE=http://etherpad.meet.jitsi:9001
# Set etherpad-lite public URL, including /p/ pad path fragment (uncomment to enable)
#ETHERPAD_PUBLIC_URL=https://etherpad.my.domain/p/
#
# Whiteboard integration
#
# Set the excalidraw-backend URL in the docker local network (uncomment to enable)
#WHITEBOARD_COLLAB_SERVER_URL_BASE=http://whiteboard.meet.jitsi
# Set the excalidraw-backend public URL (uncomment to enable)
#WHITEBOARD_COLLAB_SERVER_PUBLIC_URL=https://whiteboard.meet.my.domain
#
# Basic Jigasi configuration options (needed for SIP gateway support)
#
# SIP URI for incoming / outgoing calls
#JIGASI_SIP_URI=test@sip2sip.info
# Password for the specified SIP account as a clear text
#JIGASI_SIP_PASSWORD=passw0rd
# SIP server (use the SIP account domain if in doubt)
#JIGASI_SIP_SERVER=sip2sip.info
# SIP server port
#JIGASI_SIP_PORT=5060
# SIP server transport
#JIGASI_SIP_TRANSPORT=UDP
#
# Authentication configuration (see handbook for details)
#
# Enable authentication (will ask for login and password to join the meeting)
#ENABLE_AUTH=1
# Enable guest access (if authentication is enabled, this allows for users to be held in lobby until registered user lets them in)
#ENABLE_GUESTS=1
# Select authentication type: internal, jwt, ldap or matrix
#AUTH_TYPE=internal
# JWT authentication
#
# Application identifier
#JWT_APP_ID=my_jitsi_app_id
# Application secret known only to your token generator
#JWT_APP_SECRET=my_jitsi_app_secret
# (Optional) Set asap_accepted_issuers as a comma separated list
#JWT_ACCEPTED_ISSUERS=my_web_client,my_app_client
# (Optional) Set asap_accepted_audiences as a comma separated list
#JWT_ACCEPTED_AUDIENCES=my_server1,my_server2
# LDAP authentication (for more information see the Cyrus SASL saslauthd.conf man page)
#
# LDAP url for connection
#LDAP_URL=ldaps://ldap.domain.com/
# LDAP base DN. Can be empty
#LDAP_BASE=DC=example,DC=domain,DC=com
# LDAP user DN. Do not specify this parameter for the anonymous bind
#LDAP_BINDDN=CN=binduser,OU=users,DC=example,DC=domain,DC=com
# LDAP user password. Do not specify this parameter for the anonymous bind
#LDAP_BINDPW=LdapUserPassw0rd
# LDAP filter. Tokens example:
# %1-9 - if the input key is user@mail.domain.com, then %1 is com, %2 is domain and %3 is mail
# %s - %s is replaced by the complete service string
# %r - %r is replaced by the complete realm string
#LDAP_FILTER=(sAMAccountName=%u)
# LDAP authentication method
#LDAP_AUTH_METHOD=bind
# LDAP version
#LDAP_VERSION=3
# LDAP TLS using
#LDAP_USE_TLS=1
# List of SSL/TLS ciphers to allow
#LDAP_TLS_CIPHERS=SECURE256:SECURE128:!AES-128-CBC:!ARCFOUR-128:!CAMELLIA-128-CBC:!3DES-CBC:!CAMELLIA-128-CBC
# Require and verify server certificate
#LDAP_TLS_CHECK_PEER=1
# Path to CA cert file. Used when server certificate verify is enabled
#LDAP_TLS_CACERT_FILE=/etc/ssl/certs/ca-certificates.crt
# Path to CA certs directory. Used when server certificate verify is enabled
#LDAP_TLS_CACERT_DIR=/etc/ssl/certs
# Wether to use starttls, implies LDAPv3 and requires ldap:// instead of ldaps://
# LDAP_START_TLS=1
#
# Security
#
# Set these to strong passwords to avoid intruders from impersonating a service account
# The service(s) won't start unless these are specified
# Running ./gen-passwords.sh will update .env with strong passwords
# You may skip the Jigasi and Jibri passwords if you are not using those
# DO NOT reuse passwords
#
# XMPP password for Jicofo client connections
JICOFO_AUTH_PASSWORD=
# XMPP password for JVB client connections
JVB_AUTH_PASSWORD=
# XMPP password for Jigasi MUC client connections
JIGASI_XMPP_PASSWORD=
# XMPP password for Jigasi transcriber client connections
JIGASI_TRANSCRIBER_PASSWORD=
# XMPP recorder password for Jibri client connections
JIBRI_RECORDER_PASSWORD=
# XMPP password for Jibri client connections
JIBRI_XMPP_PASSWORD=
#
# Docker Compose options
#
# Container restart policy
#RESTART_POLICY=unless-stopped
# Jitsi image version (useful for local development)
#JITSI_IMAGE_VERSION=latest

View File

@@ -0,0 +1,17 @@
version: '3.5'
services:
# Etherpad: real-time collaborative document editing
etherpad:
image: etherpad/etherpad:2.0.3
restart: ${RESTART_POLICY:-unless-stopped}
environment:
- TITLE=${ETHERPAD_TITLE:-""}
- DEFAULT_PAD_TEXT=${ETHERPAD_DEFAULT_PAD_TEXT:-""}
- SKIN_NAME=${ETHERPAD_SKIN_NAME:-colibris}
- SKIN_VARIANTS=${ETHERPAD_SKIN_VARIANTS:-"super-light-toolbar super-light-editor light-background full-width-editor"}
- SUPPRESS_ERRORS_IN_PAD_TEXT=true
networks:
meet.jitsi:
aliases:
- etherpad.meet.jitsi

View File

@@ -0,0 +1,5 @@
# Community Examples
This folder used to contain community maintained example configurations for
Kubernetes and Traefik. They have now been migrated to the [jitsi-contrib](https://github.com/jitsi-contrib)
organization.

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
function generatePassword() {
openssl rand -hex 16
}
JICOFO_AUTH_PASSWORD=$(generatePassword)
JVB_AUTH_PASSWORD=$(generatePassword)
JIGASI_XMPP_PASSWORD=$(generatePassword)
JIBRI_RECORDER_PASSWORD=$(generatePassword)
JIBRI_XMPP_PASSWORD=$(generatePassword)
JIGASI_TRANSCRIBER_PASSWORD=$(generatePassword)
sed -i.bak \
-e "s#JICOFO_AUTH_PASSWORD=.*#JICOFO_AUTH_PASSWORD=${JICOFO_AUTH_PASSWORD}#g" \
-e "s#JVB_AUTH_PASSWORD=.*#JVB_AUTH_PASSWORD=${JVB_AUTH_PASSWORD}#g" \
-e "s#JIGASI_XMPP_PASSWORD=.*#JIGASI_XMPP_PASSWORD=${JIGASI_XMPP_PASSWORD}#g" \
-e "s#JIBRI_RECORDER_PASSWORD=.*#JIBRI_RECORDER_PASSWORD=${JIBRI_RECORDER_PASSWORD}#g" \
-e "s#JIBRI_XMPP_PASSWORD=.*#JIBRI_XMPP_PASSWORD=${JIBRI_XMPP_PASSWORD}#g" \
-e "s#JIGASI_TRANSCRIBER_PASSWORD=.*#JIGASI_TRANSCRIBER_PASSWORD=${JIGASI_TRANSCRIBER_PASSWORD}#g" \
"$(dirname "$0")/.env"

View File

@@ -0,0 +1,16 @@
version: '3.5'
services:
# Grafana: used for visualization of metrics and log data through customizable dashboards.
grafana:
image: grafana/grafana:10.2.0
environment:
- GF_ANALYTICS_REPORTING_ENABLED=false
volumes:
- ./log-analyser/grafana:/var/lib/grafana
- ./log-analyser/grafana-provisioning/dashboards/:/etc/grafana/provisioning/dashboards/
- ./log-analyser/grafana-provisioning/datasources/:/etc/grafana/provisioning/datasources/
ports:
- "3000:3000"
networks:
meet.jitsi:

View File

@@ -0,0 +1,67 @@
version: '3.5'
services:
jibri:
image: jitsi/jibri:${JITSI_IMAGE_VERSION:-stable-10590}
restart: ${RESTART_POLICY:-unless-stopped}
volumes:
- ${CONFIG}/jibri:/config:Z
shm_size: '2gb'
cap_add:
- SYS_ADMIN
environment:
- AUTOSCALER_SIDECAR_KEY_FILE
- AUTOSCALER_SIDECAR_KEY_ID
- AUTOSCALER_SIDECAR_GROUP_NAME
- AUTOSCALER_SIDECAR_HOST_ID
- AUTOSCALER_SIDECAR_INSTANCE_ID
- AUTOSCALER_SIDECAR_PORT
- AUTOSCALER_SIDECAR_REGION
- AUTOSCALER_SIDECAR_SHUTDOWN_POLLING_INTERVAL
- AUTOSCALER_SIDECAR_STATS_POLLING_INTERVAL
- AUTOSCALER_URL
- CHROMIUM_FLAGS
- DISPLAY=:0
- ENABLE_STATS_D
- IGNORE_CERTIFICATE_ERRORS
- JIBRI_WEBHOOK_SUBSCRIBERS
- JIBRI_INSTANCE_ID
- JIBRI_ENABLE_PROMETHEUS
- JIBRI_HTTP_API_EXTERNAL_PORT
- JIBRI_HTTP_API_INTERNAL_PORT
- JIBRI_RECORDING_RESOLUTION
- JIBRI_RECORDING_VIDEO_ENCODE_PRESET_RECORDING
- JIBRI_RECORDING_VIDEO_ENCODE_PRESET_STREAMING
- JIBRI_RECORDING_CONSTANT_RATE_FACTOR
- JIBRI_RECORDING_FRAMERATE
- JIBRI_RECORDING_QUEUE_SIZE
- JIBRI_RECORDING_STREAMING_MAX_BITRATE
- JIBRI_USAGE_TIMEOUT
- JIBRI_XMPP_USER
- JIBRI_XMPP_PASSWORD
- JIBRI_XORG_HORIZ_SYNC
- JIBRI_XORG_VERT_REFRESH
- JIBRI_BREWERY_MUC
- JIBRI_RECORDER_USER
- JIBRI_RECORDER_PASSWORD
- JIBRI_RECORDING_DIR
- JIBRI_FINALIZE_RECORDING_SCRIPT_PATH
- JIBRI_STRIP_DOMAIN_JID
- JIBRI_STATSD_HOST
- JIBRI_STATSD_PORT
- LOCAL_ADDRESS
- PUBLIC_URL
- TZ
- XMPP_AUTH_DOMAIN
- XMPP_DOMAIN
- XMPP_INTERNAL_MUC_DOMAIN
- XMPP_MUC_DOMAIN
- XMPP_HIDDEN_DOMAIN
- XMPP_SERVER
- XMPP_PORT
- XMPP_RECORDER_DOMAIN
- XMPP_TRUST_ALL_CERTS
depends_on:
- jicofo
networks:
meet.jitsi:

View File

@@ -0,0 +1,46 @@
ARG JITSI_REPO=jitsi
ARG BASE_TAG=latest
FROM ${JITSI_REPO}/base-java:${BASE_TAG}
LABEL org.opencontainers.image.title="Jitsi Broadcasting Infrastructure (jibri)"
LABEL org.opencontainers.image.description="Components for recording and/or streaming a conference."
LABEL org.opencontainers.image.url="https://github.com/jitsi/jibri"
LABEL org.opencontainers.image.source="https://github.com/jitsi/docker-jitsi-meet"
LABEL org.opencontainers.image.documentation="https://jitsi.github.io/handbook/"
ARG USE_CHROMIUM=0
#ARG CHROME_RELEASE=latest
# https://googlechromelabs.github.io/chrome-for-testing/
ARG CHROME_RELEASE=130.0.6723.116
COPY rootfs/ /
RUN apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
jibri \
libgl1-mesa-dri \
procps \
jitsi-upload-integrations \
jitsi-autoscaler-sidecar \
jq \
pulseaudio \
dbus \
dbus-x11 \
rtkit \
unzip \
fonts-noto \
fonts-noto-cjk \
libcap2-bin && \
/usr/bin/install-chrome.sh && \
apt-cleanup && \
adduser jibri rtkit && \
dpkgArch="$(dpkg --print-architecture)" && \
case "${dpkgArch##*-}" in \
"amd64") SC_ARCH=x86_64 ;; \
"arm64") SC_ARCH=aarch64 ;; \
*) echo "unsupported architecture"; exit 1 ;; \
esac && \
wget -qO /usr/bin/shm-check https://github.com/saghul/shm-check/releases/download/v1.0.0/shm-check-${SC_ARCH} && \
chmod +x /usr/bin/shm-check
VOLUME /config

View File

@@ -0,0 +1,19 @@
{{ $JIBRI_HTTP_API_EXTERNAL_PORT := .Env.JIBRI_HTTP_API_EXTERNAL_PORT | default "2222" -}}
{{ $SHUTDOWN_POLLING_INTERVAL := .Env.AUTOSCALER_SIDECAR_SHUTDOWN_POLLING_INTERVAL | default "60" -}}
{{ $STATS_POLLING_INTERVAL := .Env.AUTOSCALER_SIDECAR_STATS_POLLING_INTERVAL | default "30" -}}
export SHUTDOWN_POLLING_INTERVAL={{ $SHUTDOWN_POLLING_INTERVAL }}
export STATS_POLLING_INTERVAL={{ $STATS_POLLING_INTERVAL }}
export PORT={{ .Env.AUTOSCALER_SIDECAR_PORT }}
export GRACEFUL_SHUTDOWN_SCRIPT="/opt/jitsi/jibri/wait_graceful_shutdown.sh"
export TERMINATE_SCRIPT="/opt/jitsi/shutdown.sh"
export ENABLE_REPORT_STATS=true
export POLLING_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/poll"
export STATUS_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/status"
export SHUTDOWN_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/shutdown"
export STATS_RETRIEVE_URL="http://localhost:{{ $JIBRI_HTTP_API_EXTERNAL_PORT }}/jibri/api/v1.0/health"
export STATS_REPORT_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/stats"
export ASAP_SIGNING_KEY_FILE="{{ .Env.AUTOSCALER_SIDECAR_KEY_FILE }}"
export ASAP_JWT_KID="{{ .Env.AUTOSCALER_SIDECAR_KEY_ID }}"
export INSTANCE_TYPE="jibri"
export INSTANCE_ID="{{ .Env.AUTOSCALER_SIDECAR_INSTANCE_ID }}"
export INSTANCE_METADATA='{"environment":"{{ .Env.XMPP_ENV_NAME }}","region":"{{ .Env.AUTOSCALER_SIDECAR_REGION }}","group":"{{ .Env.AUTOSCALER_SIDECAR_GROUP_NAME }}","name":"{{ .Env.JIBRI_INSTANCE_ID }}","version":"{{ .Env.JIBRI_VERSION }}","privateIp":"{{ .Env.LOCAL_ADDRESS }}","hostId":"{{ .Env.AUTOSCALER_SIDECAR_HOST_ID }}"}'

View File

@@ -0,0 +1,96 @@
{{ $IGNORE_CERTIFICATE_ERRORS := .Env.IGNORE_CERTIFICATE_ERRORS | default "false" | toBool -}}
{{ $ENABLE_PROMETHEUS := .Env.JIBRI_ENABLE_PROMETHEUS | default "false" | toBool -}}
{{ $JIBRI_RECORDING_RESOLUTION := .Env.JIBRI_RECORDING_RESOLUTION | default "1280x720" -}}
{{ $JIBRI_RECORDING_VIDEO_ENCODE_PRESET_RECORDING := .Env.JIBRI_RECORDING_VIDEO_ENCODE_PRESET_RECORDING | default "ultrafast" -}}
{{ $JIBRI_RECORDING_VIDEO_ENCODE_PRESET_STREAMING := .Env.JIBRI_RECORDING_VIDEO_ENCODE_PRESET_STREAMING | default "veryfast" -}}
{{ $JIBRI_RECORDING_CONSTANT_RATE_FACTOR := .Env.JIBRI_RECORDING_CONSTANT_RATE_FACTOR | default 25 -}}
{{ $JIBRI_RECORDING_FRAMERATE := .Env.JIBRI_RECORDING_FRAMERATE | default 30 -}}
{{ $JIBRI_RECORDING_QUEUE_SIZE := .Env.JIBRI_RECORDING_QUEUE_SIZE | default 4096 -}}
{{ $JIBRI_RECORDING_STREAMING_MAX_BITRATE := .Env.JIBRI_RECORDING_STREAMING_MAX_BITRATE | default "2976k" -}}
{{ $JIBRI_SINGLE_USE_MODE := .Env.JIBRI_SINGLE_USE_MODE | default "false" -}}
{{ $STATSD_HOST := .Env.JIBRI_STATSD_HOST | default "localhost" -}}
{{ $STATSD_PORT := .Env.JIBRI_STATSD_PORT | default "8125" -}}
jibri {
// A unique identifier for this Jibri
id = "{{ .Env.JIBRI_INSTANCE_ID }}"
// Whether or not Jibri should return to idle state after handling
// (successfully or unsuccessfully) a request. A value of 'true'
// here means that a Jibri will NOT return back to the IDLE state
// and will need to be restarted in order to be used again.
single-use-mode = {{ $JIBRI_SINGLE_USE_MODE }}
api {
{{ if or .Env.JIBRI_HTTP_API_EXTERNAL_PORT .Env.JIBRI_HTTP_API_INTERNAL_PORT -}}
http {
{{ if .Env.JIBRI_HTTP_API_EXTERNAL_PORT -}}
external-api-port = {{ .Env.JIBRI_HTTP_API_EXTERNAL_PORT }}
{{ end -}}
{{ if .Env.JIBRI_HTTP_API_INTERNAL_PORT -}}
internal-api-port = {{ .Env.JIBRI_HTTP_API_INTERNAL_PORT }}
{{ end -}}
}
{{ end -}}
}
recording {
recordings-directory = "{{ .Env.JIBRI_RECORDING_DIR | default "/config/recordings" }}"
{{ if .Env.JIBRI_FINALIZE_RECORDING_SCRIPT_PATH -}}
finalize-script = "{{ .Env.JIBRI_FINALIZE_RECORDING_SCRIPT_PATH }}"
{{ end -}}
}
{{ if .Env.JIBRI_WEBHOOK_SUBSCRIBERS -}}
webhook {
subscribers = [{{ range $index, $element := (splitList "," .Env.JIBRI_WEBHOOK_SUBSCRIBERS | compact) }}{{ if gt $index 0}},{{ end }}"{{ $element }}"{{ end }}]
}{{ end }}
ffmpeg {
resolution = "{{ $JIBRI_RECORDING_RESOLUTION }}"
// The audio source that will be used to capture audio on Linux
audio-source = "pulse"
// The audio device that will be used to capture audio on Linux
audio-device = "default"
framerate = {{ $JIBRI_RECORDING_FRAMERATE }}
queue-size = {{ $JIBRI_RECORDING_QUEUE_SIZE }}
streaming-max-bitrate = "{{ $JIBRI_RECORDING_STREAMING_MAX_BITRATE }}"
// Available presets: ultrafast, superfast, veryfast, faster, fast, medium,
// slow, slower, veryslow, placebo
video-encode-preset-streaming = "{{ $JIBRI_RECORDING_VIDEO_ENCODE_PRESET_STREAMING }}"
video-encode-preset-recording = "{{ $JIBRI_RECORDING_VIDEO_ENCODE_PRESET_RECORDING }}"
// The range of the CRF scale is 0-51, where 0 is lossless,
// 23 is the default, and 51 is worst quality possible.
h264-constant-rate-factor = {{ $JIBRI_RECORDING_CONSTANT_RATE_FACTOR }}
}
{{ if .Env.CHROMIUM_FLAGS -}}
chrome {
// The flags which will be passed to chromium when launching
flags = [
"{{ join "\",\"" (splitList "," .Env.CHROMIUM_FLAGS | compact) }}"
]
}
{{ else if $IGNORE_CERTIFICATE_ERRORS -}}
chrome {
flags = [
"--use-fake-ui-for-media-stream",
"--start-maximized",
"--kiosk",
"--enabled",
"--autoplay-policy=no-user-gesture-required",
"--ignore-certificate-errors"
]
}
{{ end -}}
stats {
{{- if .Env.ENABLE_STATS_D }}
enable-stats-d = {{ .Env.ENABLE_STATS_D }}
host = "{{ $STATSD_HOST }}"
port = {{ $STATSD_PORT }}
{{- end }}
prometheus.enabled = {{ $ENABLE_PROMETHEUS }}
}
}
include "xmpp.conf"
include "/config/custom-jibri.conf"

View File

@@ -0,0 +1,33 @@
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
org.jitsi.utils.logging2.JitsiLogFormatter.programname=Jibri
java.util.logging.FileHandler.level = FINE
java.util.logging.FileHandler.pattern = /config/logs/log.%g.txt
java.util.logging.FileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
java.util.logging.FileHandler.count = 10
java.util.logging.FileHandler.limit = 10000000
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.level = FINE
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.pattern = /config/logs/ffmpeg.%g.txt
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.count = 10
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.limit = 10000000
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.level = FINE
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.pattern = /config/logs/pjsua.%g.txt
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.count = 10
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.limit = 10000000
org.jitsi.jibri.selenium.util.BrowserFileHandler.level = FINE
org.jitsi.jibri.selenium.util.BrowserFileHandler.pattern = /config/logs/browser.%g.txt
org.jitsi.jibri.selenium.util.BrowserFileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
org.jitsi.jibri.selenium.util.BrowserFileHandler.count = 10
org.jitsi.jibri.selenium.util.BrowserFileHandler.limit = 10000000
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
org.jitsi.level = FINE
org.glassfish.level = INFO

View File

@@ -0,0 +1,77 @@
{{ $JIBRI_BREWERY_MUC := .Env.JIBRI_BREWERY_MUC | default "jibribrewery" -}}
{{ $XMPP_MUC_DOMAIN := .Env.XMPP_MUC_DOMAIN | default "muc.meet.jitsi" -}}
{{ $XMPP_MUC_DOMAIN_PREFIX := (split "." $XMPP_MUC_DOMAIN)._0 -}}
{{ $JIBRI_STRIP_DOMAIN_JID := .Env.JIBRI_STRIP_DOMAIN_JID | default $XMPP_MUC_DOMAIN_PREFIX -}}
{{ $JIBRI_RECORDER_USER := .Env.JIBRI_RECORDER_USER | default "recorder" -}}
{{ $JIBRI_USAGE_TIMEOUT := .Env.JIBRI_USAGE_TIMEOUT | default "0" -}}
{{ $JIBRI_XMPP_USER := .Env.JIBRI_XMPP_USER | default "jibri" -}}
{{ $XMPP_AUTH_DOMAIN := .Env.XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $XMPP_DOMAIN := .Env.XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $XMPP_INTERNAL_MUC_DOMAIN := .Env.XMPP_INTERNAL_MUC_DOMAIN | default "internal-muc.meet.jitsi" -}}
{{ $XMPP_HIDDEN_DOMAIN := .Env.XMPP_HIDDEN_DOMAIN | default "hidden.meet.jitsi" -}}
{{ $XMPP_TRUST_ALL_CERTS := .Env.XMPP_TRUST_ALL_CERTS | default "true" | toBool -}}
{{ $XMPP_PORT := .Env.XMPP_PORT | default "5222" -}}
{{ $XMPP_SERVER := .Env.XMPP_SERVER | default "xmpp.meet.jitsi" -}}
{{ $XMPP_SERVERS := splitList "," $XMPP_SERVER | compact -}}
{{/* assign env from context, preserve during range when . is re-assigned */}}
{{ $ENV := .Env -}}
jibri.api.xmpp.environments = [
// See example_xmpp_envs.conf for an example of what is expected here
{{ range $index, $element := $XMPP_SERVERS -}}
{{ $SERVER := splitn ":" 2 $element }}
{
// A user-friendly name for this environment
name = "{{ $ENV.XMPP_ENV_NAME }}-{{$index}}"
// A list of XMPP server hosts to which we'll connect
xmpp-server-hosts = [
"{{ $SERVER._0 }}"
]
// The base XMPP domain
xmpp-domain = "{{ $XMPP_DOMAIN }}"
{{ if $ENV.PUBLIC_URL -}}
// An (optional) base url the Jibri will join if it is set
base-url = "{{ $ENV.PUBLIC_URL }}"
{{ end -}}
// The MUC we'll join to announce our presence for
// recording and streaming services
control-muc {
domain = "{{ $XMPP_INTERNAL_MUC_DOMAIN }}"
room-name = "{{ $JIBRI_BREWERY_MUC }}"
nickname = "{{ $ENV.JIBRI_INSTANCE_ID }}"
}
// The login information for the control MUC
control-login {
domain = "{{ $XMPP_AUTH_DOMAIN }}"
port = "{{ $SERVER._1 | default $XMPP_PORT }}"
username = "{{ $JIBRI_XMPP_USER }}"
password = "{{ $ENV.JIBRI_XMPP_PASSWORD }}"
}
// The login information the selenium web client will use
call-login {
domain = "{{ $XMPP_HIDDEN_DOMAIN }}"
username = "{{ $JIBRI_RECORDER_USER }}"
password = "{{ $ENV.JIBRI_RECORDER_PASSWORD }}"
}
// The value we'll strip from the room JID domain to derive
// the call URL
strip-from-room-domain = "{{ $JIBRI_STRIP_DOMAIN_JID }}."
// How long Jibri sessions will be allowed to last before
// they are stopped. A value of 0 allows them to go on
// indefinitely
usage-timeout = "{{ $JIBRI_USAGE_TIMEOUT }}"
// Whether or not we'll automatically trust any cert on
// this XMPP domain
trust-all-xmpp-certs = {{ $XMPP_TRUST_ALL_CERTS }}
}
{{ end }}
]

View File

@@ -0,0 +1,122 @@
{{ $JIBRI_RECORDING_RESOLUTION := .Env.JIBRI_RECORDING_RESOLUTION | default "1280x720" -}}
{{ $JIBRI_HORIZ_SYNC := .Env.JIBRI_XORG_HORIZ_SYNC | default "5.0 - 1000.0" -}}
{{ $JIBRI_VERT_REFRESH := .Env.JIBRI_XORG_VERT_REFRESH | default "5.0 - 200.0" -}}
# This xorg configuration file is meant to be used by xpra
# to start a dummy X11 server.
# For details, please see:
# https://xpra.org/Xdummy.html
Section "ServerFlags"
Option "DontVTSwitch" "true"
Option "AllowMouseOpenFail" "true"
Option "PciForceNone" "true"
Option "AutoEnableDevices" "false"
Option "AutoAddDevices" "false"
EndSection
Section "Device"
Identifier "dummy_videocard"
Driver "dummy"
Option "ConstantDPI" "true"
#VideoRam 4096000
#VideoRam 256000
VideoRam 192000
EndSection
Section "Monitor"
Identifier "dummy_monitor"
HorizSync {{ $JIBRI_HORIZ_SYNC }}
VertRefresh {{ $JIBRI_VERT_REFRESH }}
#This can be used to get a specific DPI, but only for the default resolution:
#DisplaySize 508 317
#NOTE: the highest modes will not work without increasing the VideoRam
# for the dummy video card.
Modeline "32768x32768" 15226.50 32768 35800 39488 46208 32768 32771 32781 32953
Modeline "32768x16384" 7516.25 32768 35544 39192 45616 16384 16387 16397 16478
Modeline "16384x8192" 2101.93 16384 16416 24400 24432 8192 8390 8403 8602
Modeline "8192x4096" 424.46 8192 8224 9832 9864 4096 4195 4202 4301
Modeline "5496x1200" 199.13 5496 5528 6280 6312 1200 1228 1233 1261
Modeline "5280x1080" 169.96 5280 5312 5952 5984 1080 1105 1110 1135
Modeline "5280x1200" 191.40 5280 5312 6032 6064 1200 1228 1233 1261
Modeline "5120x3200" 199.75 5120 5152 5904 5936 3200 3277 3283 3361
Modeline "4800x1200" 64.42 4800 4832 5072 5104 1200 1229 1231 1261
Modeline "3840x2880" 133.43 3840 3872 4376 4408 2880 2950 2955 3025
Modeline "3840x2560" 116.93 3840 3872 4312 4344 2560 2622 2627 2689
Modeline "3840x2048" 91.45 3840 3872 4216 4248 2048 2097 2101 2151
Modeline "3840x1080" 100.38 3840 3848 4216 4592 1080 1081 1084 1093
Modeline "3600x1200" 106.06 3600 3632 3984 4368 1200 1201 1204 1214
Modeline "3288x1080" 39.76 3288 3320 3464 3496 1080 1106 1108 1135
Modeline "2048x2048" 49.47 2048 2080 2264 2296 2048 2097 2101 2151
Modeline "2048x1536" 80.06 2048 2104 2312 2576 1536 1537 1540 1554
Modeline "2560x1600" 47.12 2560 2592 2768 2800 1600 1639 1642 1681
Modeline "2560x1440" 42.12 2560 2592 2752 2784 1440 1475 1478 1513
Modeline "1920x1440" 69.47 1920 1960 2152 2384 1440 1441 1444 1457
Modeline "1920x1200" 26.28 1920 1952 2048 2080 1200 1229 1231 1261
Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135
Modeline "1680x1050" 20.08 1680 1712 1784 1816 1050 1075 1077 1103
Modeline "1600x1200" 22.04 1600 1632 1712 1744 1200 1229 1231 1261
Modeline "1600x900" 33.92 1600 1632 1760 1792 900 921 924 946
Modeline "1440x900" 30.66 1440 1472 1584 1616 900 921 924 946
ModeLine "1366x768" 72.00 1366 1414 1446 1494 768 771 777 803
Modeline "1280x1024" 31.50 1280 1312 1424 1456 1024 1048 1052 1076
Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841
Modeline "1280x768" 23.11 1280 1312 1392 1424 768 786 789 807
Modeline "1360x768" 24.49 1360 1392 1480 1512 768 786 789 807
Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807
Modeline "768x1024" 19.50 768 800 872 904 1024 1048 1052 1076
#common resolutions for android devices (both orientations):
Modeline "800x1280" 25.89 800 832 928 960 1280 1310 1315 1345
Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841
Modeline "720x1280" 30.22 720 752 864 896 1280 1309 1315 1345
Modeline "1280x720" 27.41 1280 1312 1416 1448 720 737 740 757
Modeline "768x1024" 24.93 768 800 888 920 1024 1047 1052 1076
Modeline "1024x768" 23.77 1024 1056 1144 1176 768 785 789 807
Modeline "600x1024" 19.90 600 632 704 736 1024 1047 1052 1076
Modeline "1024x600" 18.26 1024 1056 1120 1152 600 614 617 631
Modeline "536x960" 16.74 536 568 624 656 960 982 986 1009
Modeline "960x536" 15.23 960 992 1048 1080 536 548 551 563
Modeline "600x800" 15.17 600 632 688 720 800 818 822 841
Modeline "800x600" 14.50 800 832 880 912 600 614 617 631
Modeline "480x854" 13.34 480 512 560 592 854 873 877 897
Modeline "848x480" 12.09 848 880 920 952 480 491 493 505
Modeline "480x800" 12.43 480 512 552 584 800 818 822 841
Modeline "800x480" 11.46 800 832 872 904 480 491 493 505
#resolutions for android devices (both orientations)
#minus the status bar
#38px status bar (and width rounded up)
Modeline "800x1242" 25.03 800 832 920 952 1242 1271 1275 1305
Modeline "1280x762" 22.93 1280 1312 1392 1424 762 780 783 801
Modeline "720x1242" 29.20 720 752 856 888 1242 1271 1276 1305
Modeline "1280x682" 25.85 1280 1312 1408 1440 682 698 701 717
Modeline "768x986" 23.90 768 800 888 920 986 1009 1013 1036
Modeline "1024x730" 22.50 1024 1056 1136 1168 730 747 750 767
Modeline "600x986" 19.07 600 632 704 736 986 1009 1013 1036
Modeline "1024x562" 17.03 1024 1056 1120 1152 562 575 578 591
Modeline "536x922" 16.01 536 568 624 656 922 943 947 969
Modeline "960x498" 14.09 960 992 1040 1072 498 509 511 523
Modeline "600x762" 14.39 600 632 680 712 762 779 783 801
Modeline "800x562" 13.52 800 832 880 912 562 575 578 591
Modeline "480x810" 12.59 480 512 552 584 810 828 832 851
Modeline "848x442" 11.09 848 880 920 952 442 452 454 465
Modeline "480x762" 11.79 480 512 552 584 762 779 783 801
EndSection
Section "Screen"
Identifier "dummy_screen"
Device "dummy_videocard"
Monitor "dummy_monitor"
DefaultDepth 24
SubSection "Display"
Viewport 0 0
Depth 24
Modes {{ $JIBRI_RECORDING_RESOLUTION | quote }}
EndSubSection
EndSection
Section "ServerLayout"
Identifier "dummy_layout"
Screen "dummy_screen"
EndSection

View File

@@ -0,0 +1,3 @@
{
"CommandLineFlagSecurityWarningsEnabled": false
}

View File

@@ -0,0 +1,93 @@
#!/usr/bin/with-contenv bash
# Check if the SYS_ADMIN cap is set
if ! capsh --has-p=cap_sys_admin; then
echo "Required capability SYS_ADMIN is missing"
exit 1
fi
# Check if /dev/shm is large enough (2GB at least)
if ! shm-check; then
echo "/dev/shm must be at least 2GB in size"
exit 1
fi
if [[ -z $JIBRI_RECORDER_PASSWORD || -z $JIBRI_XMPP_PASSWORD ]]; then
echo 'FATAL ERROR: Jibri recorder password and auth password must be set'
exit 1
fi
OLD_JIBRI_RECORDER_PASSWORD=passw0rd
if [[ "$JIBRI_RECORDER_PASSWORD" == "$OLD_JIBRI_RECORDER_PASSWORD" ]]; then
echo 'FATAL ERROR: Jibri recorder password must be changed, check the README'
exit 1
fi
OLD_JIBRI_XMPP_PASSWORD=passw0rd
if [[ "$JIBRI_XMPP_PASSWORD" == "$OLD_JIBRI_XMPP_PASSWORD" ]]; then
echo 'FATAL ERROR: Jibri auth password must be changed, check the README'
exit 1
fi
# DISPLAY is necessary for start
[ -z "${DISPLAY}" ] \
&& ( echo -e "\e[31mERROR: Please set DISPLAY variable.\e[39m"; kill 1; exit 1 )
# script for finalizing must have executing bit.
[ ! -z "${JIBRI_FINALIZE_RECORDING_SCRIPT_PATH}" ] \
&& [ -f "${JIBRI_FINALIZE_RECORDING_SCRIPT_PATH}" ] \
&& [ ! -x "${JIBRI_FINALIZE_RECORDING_SCRIPT_PATH}" ] \
&& chmod +x ${JIBRI_FINALIZE_RECORDING_SCRIPT_PATH}
# set random jibri nickname for the instance if is not set
[ -z "${JIBRI_INSTANCE_ID}" ] && export JIBRI_INSTANCE_ID="jibri-$(date +%N)"
# check for AUTOSCALER_URL, AUTOSCALER_SIDECAR_KEY_FILE and AUTOSCALER_SIDECAR_KEY_ID as indicator that sidecar should be enabled
if [ -n "$AUTOSCALER_URL" ]; then
if [ -z "$AUTOSCALER_SIDECAR_KEY_FILE" ]; then
export AUTOSCALER_SIDECAR_KEY_FILE="/etc/jitsi/autoscaler-sidecar/asap.pem"
fi
if [ -z "$AUTOSCALER_SIDECAR_KEY_ID" ]; then
# assume key id is equal to the base real path of the key file minus .pem
export AUTOSCALER_SIDECAR_KEY_ID="$(basename "$(realpath "$AUTOSCALER_SIDECAR_KEY_FILE")" | tr -d '.pem')"
fi
if [ -f "$AUTOSCALER_SIDECAR_KEY_FILE" ]; then
echo "AUTOSCALER_URL found, enabling autoscaler sidecar"
export JIBRI_VERSION="$(dpkg -s jibri | grep Version | awk '{print $2}' | sed 's/..$//')"
[ -z "$AUTOSCALER_SIDECAR_PORT" ] && export AUTOSCALER_SIDECAR_PORT="6000"
[ -z "$JIBRI_WEBHOOK_SUBSCRIBERS" ] && export JIBRI_WEBHOOK_SUBSCRIBERS="http://localhost:$AUTOSCALER_SIDECAR_PORT/hook"
[ -z "$AUTOSCALER_SIDECAR_INSTANCE_ID" ] && export AUTOSCALER_SIDECAR_INSTANCE_ID="$JIBRI_INSTANCE_ID"
[ -z "$AUTOSCALER_SIDECAR_REGION" ] && export AUTOSCALER_SIDECAR_REGION="docker"
[ -z "$AUTOSCALER_SIDECAR_GROUP_NAME" ] && export AUTOSCALER_SIDECAR_GROUP_NAME="docker-jibri"
[ -z "$LOCAL_ADDRESS" ] && export LOCAL_ADDRESS="$(ip route get 1 | grep -oP '(?<=src ).*' | awk '{ print $1 '})"
mkdir -p /etc/jitsi/autoscaler-sidecar
tpl /defaults/autoscaler-sidecar.config > /etc/jitsi/autoscaler-sidecar/config
else
echo "No key file at $AUTOSCALER_SIDECAR_KEY_FILE, leaving autoscaler sidecar disabled"
fi
else
echo "No AUTOSCALER_URL defined, leaving autoscaler sidecar disabled"
fi
# maintain backward compatibility with older variable
[ -z "${XMPP_HIDDEN_DOMAIN}" ] && export XMPP_HIDDEN_DOMAIN="$XMPP_RECORDER_DOMAIN"
# always recreate configs
tpl /defaults/jibri.conf > /etc/jitsi/jibri/jibri.conf
tpl /defaults/xmpp.conf > /etc/jitsi/jibri/xmpp.conf
tpl /defaults/logging.properties > /etc/jitsi/jibri/logging.properties
tpl /defaults/xorg-video-dummy.conf > /etc/jitsi/jibri/xorg-video-dummy.conf
# make recording dir
[ -z "${JIBRI_RECORDING_DIR}" ] && export JIBRI_RECORDING_DIR=/config/recordings
mkdir -p ${JIBRI_RECORDING_DIR}
chown -R jibri ${JIBRI_RECORDING_DIR}
# make logs dir
JIBRI_LOGS_DIR=/config/logs
mkdir -p ${JIBRI_LOGS_DIR}
chown -R jibri ${JIBRI_LOGS_DIR}

View File

@@ -0,0 +1,2 @@
/home/jibri/.config true jibri 0640 0750
/home/jibri false jibri 0640 0750

View File

@@ -0,0 +1,3 @@
{
"CommandLineFlagSecurityWarningsEnabled": false
}

View File

@@ -0,0 +1,65 @@
#!/usr/bin/pulseaudio -nF
#
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
# This startup script is used only if PulseAudio is started per-user
# (i.e. not in system mode)
# Customized for Jibri
.fail
### Automatically restore the volume of streams and devices
load-module module-device-restore
load-module module-stream-restore
load-module module-card-restore
### Automatically augment property information from .desktop files
### stored in /usr/share/application
load-module module-augment-properties
### Should be after module-*-restore but before module-*-detect
load-module module-switch-on-port-available
### Load several protocols
load-module module-native-protocol-unix
### Automatically restore the default sink/source when changed by the user
### during runtime
### NOTE: This should be loaded as early as possible so that subsequent modules
### that look up the default sink/source get the right value
load-module module-default-device-restore
### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink
### Honour intended role device property
load-module module-intended-roles
### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle
### If autoexit on idle is enabled we want to make sure we only quit
### when no local session needs us anymore.
#.ifexists module-console-kit.so
#load-module module-console-kit
#.endif
#.ifexists module-systemd-login.so
#load-module module-systemd-login
#.endif
### Enable positioned event sounds
load-module module-position-event-sounds

View File

@@ -0,0 +1,5 @@
#!/usr/bin/with-contenv bash
DAEMON="/usr/bin/Xorg -nocursor -noreset +extension RANDR +extension RENDER -logfile /tmp/xorg.log -config /etc/jitsi/jibri/xorg-video-dummy.conf ${DISPLAY}"
exec s6-setuidgid jibri /bin/bash -c "exec $DAEMON"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/with-contenv bash
DAEMON="/usr/bin/icewm-session"
exec s6-setuidgid jibri /bin/bash -c "exec $DAEMON"

View File

@@ -0,0 +1,4 @@
#!/usr/bin/with-contenv bash
HOME=/home/jibri
exec s6-setuidgid jibri /bin/bash -c "exec /usr/bin/pulseaudio"

View File

@@ -0,0 +1,9 @@
#!/usr/bin/with-contenv bash
# When jibri is shutdown (or gracefully shutdown), it exits with code 255.
# In this case, we don't want S6 to restart the service. We want to stop all
# services and shutdown the container.
if [[ $1 -eq 255 ]]; then
s6-svscanctl -t /var/run/s6/services
fi

View File

@@ -0,0 +1,12 @@
#!/usr/bin/with-contenv bash
# we have to set it, otherwise chrome won't find ~/.asoundrc file
HOME=/home/jibri
DAEMON=/opt/jitsi/jibri/launch.sh
CHROME_BIN_PATH="$(which google-chrome)"
[ $? -ne 0 ] && CHROME_BIN_PATH="$(which chromium)"
# pre-warm google chrome before jibri launches to ensure fast chrome launch during recordings
[ -n "$CHROME_BIN_PATH" ] && s6-setuidgid jibri $CHROME_BIN_PATH --timeout=1000 --headless about:blank
exec s6-setuidgid jibri /bin/bash -c "exec $DAEMON"

View File

@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash
if [[ -n "$AUTOSCALER_URL" ]] && [[ -f "/etc/jitsi/autoscaler-sidecar/config" ]]; then
DAEMON="/usr/bin/node /usr/share/jitsi-autoscaler-sidecar/app.js"
exec s6-setuidgid autoscaler-sidecar /bin/bash -c ". /etc/jitsi/autoscaler-sidecar/config && exec $DAEMON"
else
# if autoscaler-sidecar should not be started,
# prevent s6 from restarting this script again and again
s6-svc -O /var/run/s6/services/50-autoscaler-sidecar
fi

View File

@@ -0,0 +1,9 @@
daemonize = no
high-priority = no
realtime-scheduling = yes
realtime-priority = 5
exit-idle-time = -1
flat-volumes = no
deferred-volume-safety-margin-usec = 1
log-level = info
log-target = file:/config/logs/pulse.log

View File

@@ -0,0 +1,8 @@
.include /etc/pulse/default.pa
# Load the virtual sink and set it as default
load-module module-virtual-sink sink_name=jibri-loop
set-default-sink jibri-loop
# set the monitor of the jibri-loop sink to be the default source
set-default-source jibri-loop.monitor

View File

@@ -0,0 +1,11 @@
#!/usr/bin/with-contenv bash
# notify the sidecar of imminent shutdown
PORT=${AUTOSCALER_SIDECAR_PORT:-6000}
curl -d '{}' -v 0:$PORT/hook/v1/shutdown
sleep 10
# signal jibri to shutdown via rest api
/opt/jitsi/jibri/shutdown.sh
# shutdown everything else
s6-svscanctl -t /var/run/s6/services

View File

@@ -0,0 +1,43 @@
#!/bin/bash
set -o pipefail -xeu
dpkgArch="$(dpkg --print-architecture)"
if [ "${USE_CHROMIUM}" = 1 -o "${dpkgArch##*-}" = "arm64" ]; then
echo "Using Debian's Chromium"
apt-dpkg-wrap apt-get install -y chromium chromium-driver chromium-sandbox
chromium --version
else
if [ "${CHROME_RELEASE}" = "latest" ]; then
wget -qO - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmour > /etc/apt/trusted.gpg.d/google.gpg
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list
apt-dpkg-wrap apt-get update
apt-dpkg-wrap apt-get install -y google-chrome-stable
else
CHROME_DEB="/tmp/google-chrome-stable_${CHROME_RELEASE}-1_amd64.deb"
curl -4so ${CHROME_DEB} "http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_RELEASE}-1_amd64.deb"
apt-dpkg-wrap apt-get install -y ${CHROME_DEB}
rm -f ${CHROME_DEB}
fi
google-chrome --version
BASE_URL=https://googlechromelabs.github.io/chrome-for-testing
if [ "${CHROME_RELEASE}" = "latest" ]; then
CHROMEDRIVER_RELEASE="$(curl -4Ls ${BASE_URL}/LATEST_RELEASE_STABLE)"
else
CHROMEDRIVER_MAJOR_RELEASE=$(echo $CHROME_RELEASE | cut -d. -f1)
CHROMEDRIVER_RELEASE="$(curl -4Ls ${BASE_URL}/LATEST_RELEASE_${CHROMEDRIVER_MAJOR_RELEASE})"
fi
CHROMEDRIVER_ZIP="/tmp/chromedriver_linux64.zip"
curl -4Lso ${CHROMEDRIVER_ZIP} "https://storage.googleapis.com/chrome-for-testing-public/${CHROMEDRIVER_RELEASE}/linux64/chromedriver-linux64.zip"
unzip ${CHROMEDRIVER_ZIP} -d /tmp/
mv /tmp/chromedriver-linux64/chromedriver /usr/bin/
chmod +x /usr/bin/chromedriver
rm -rf /tmp/chromedriver*
fi
chromedriver --version

View File

@@ -0,0 +1,17 @@
ARG JITSI_REPO=jitsi
ARG BASE_TAG=latest
FROM ${JITSI_REPO}/base-java:${BASE_TAG}
LABEL org.opencontainers.image.title="Jitsi Conference Focus (jicofo)"
LABEL org.opencontainers.image.description="Server-side focus component that manages media sessions and acts as load balancer."
LABEL org.opencontainers.image.url="https://github.com/jitsi/jicofo"
LABEL org.opencontainers.image.source="https://github.com/jitsi/docker-jitsi-meet"
LABEL org.opencontainers.image.documentation="https://jitsi.github.io/handbook/"
RUN apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y jicofo && \
apt-cleanup
COPY rootfs/ /
VOLUME /config

View File

@@ -0,0 +1,338 @@
{{ $ENABLE_AUTH := .Env.ENABLE_AUTH | default "0" -}}
{{ $ENABLE_VISITORS := .Env.ENABLE_VISITORS | default "0" | toBool -}}
{{ $JICOFO_ENABLE_AUTH := .Env.JICOFO_ENABLE_AUTH | default $ENABLE_AUTH | toBool -}}
{{ $AUTH_TYPE := .Env.AUTH_TYPE | default "internal" -}}
{{ $JICOFO_AUTH_TYPE := .Env.JICOFO_AUTH_TYPE | default $AUTH_TYPE -}}
{{ $JICOFO_AUTH_LIFETIME := .Env.JICOFO_AUTH_LIFETIME | default "24 hours" -}}
{{ $ENABLE_SCTP := .Env.ENABLE_SCTP | default "1" | toBool -}}
{{ $ENABLE_RECORDING := .Env.ENABLE_RECORDING | default "0" | toBool -}}
{{ $ENABLE_TRANSCRIPTIONS := .Env.ENABLE_TRANSCRIPTIONS | default "0" | toBool -}}
{{ $ENABLE_OCTO := .Env.ENABLE_OCTO | default "0" | toBool -}}
{{ $ENABLE_OCTO_SCTP := .Env.ENABLE_OCTO_SCTP | default $ENABLE_SCTP | toBool -}}
{{ $ENABLE_AUTO_LOGIN := .Env.ENABLE_AUTO_LOGIN | default "1" | toBool -}}
{{ $ENABLE_REST := .Env.JICOFO_ENABLE_REST | default "0" | toBool -}}
{{ $ENABLE_JVB_XMPP_SERVER := .Env.ENABLE_JVB_XMPP_SERVER | default "0" | toBool -}}
{{ $ENABLE_SHARED_DOCUMENT_RANDOM_NAME := .Env.ENABLE_SHARED_DOCUMENT_RANDOM_NAME | default "0" | toBool -}}
{{ $HEALTH_CHECKS_USE_PRESENCE := .Env.JICOFO_HEALTH_CHECKS_USE_PRESENCE | default "0" | toBool -}}
{{ $ICE_FAILURE_INTERVAL := .Env.JICOFO_ICE_FAILURE_INTERVAL | default "60" -}}
{{ $ICE_FAILURE_MIN_ENDPOINTS := .Env.JICOFO_ICE_FAILURE_MIN_ENDPOINTS | default "40" -}}
{{ $ICE_FAILURE_THRESHOLD := .Env.JICOFO_ICE_FAILURE_THRESHOLD | default "0.1" -}}
{{ $JIBRI_BREWERY_MUC := .Env.JIBRI_BREWERY_MUC | default "jibribrewery" -}}
{{ $JIGASI_BREWERY_MUC := .Env.JIGASI_BREWERY_MUC | default "jigasibrewery" -}}
{{ $JVB_BREWERY_MUC := .Env.JVB_BREWERY_MUC | default "jvbbrewery" -}}
{{ $JIBRI_PENDING_TIMEOUT := .Env.JIBRI_PENDING_TIMEOUT | default "90 seconds" -}}
{{ $JVB_XMPP_AUTH_DOMAIN := .Env.JVB_XMPP_AUTH_DOMAIN | default "auth.jvb.meet.jitsi" -}}
{{ $JVB_XMPP_INTERNAL_MUC_DOMAIN := .Env.JVB_XMPP_INTERNAL_MUC_DOMAIN | default "muc.jvb.meet.jitsi" -}}
{{ $JVB_XMPP_PORT := .Env.JVB_XMPP_PORT | default "6222" -}}
{{ $JVB_XMPP_SERVER := .Env.JVB_XMPP_SERVER | default "xmpp.jvb.meet.jitsi" -}}
{{ $RESTART_REQUEST_INTERVAL := .Env.JICOFO_RESTART_REQUEST_INTERVAL | default "60" -}}
{{ $VISITORS_MAX_VISITORS_PER_NODE := .Env.VISITORS_MAX_VISITORS_PER_NODE | default "250" }}
{{ $VISITORS_MUC_PREFIX := .Env.PROSODY_VISITORS_MUC_PREFIX | default "muc" -}}
{{ $VISITORS_REQUIRE_MUC_CONFIG := .Env.JICOFO_VISITORS_REQUIRE_MUC_CONFIG | default "0" | toBool }}
{{ $VISITORS_XMPP_AUTH_DOMAIN := .Env.VISITORS_XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $VISITORS_XMPP_DOMAIN := .Env.VISITORS_XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $VISITORS_XMPP_SERVER := .Env.VISITORS_XMPP_SERVER | default "" -}}
{{ $VISITORS_XMPP_SERVERS := splitList "," $VISITORS_XMPP_SERVER | compact -}}
{{ $VISITORS_XMPP_PORT := .Env.VISITORS_XMPP_PORT | default 52220 }}
{{ $XMPP_AUTH_DOMAIN := .Env.XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $XMPP_MUC_DOMAIN := .Env.XMPP_MUC_DOMAIN | default "muc.meet.jitsi" -}}
{{ $XMPP_INTERNAL_MUC_DOMAIN := .Env.XMPP_INTERNAL_MUC_DOMAIN | default "internal-muc.meet.jitsi" -}}
{{ $XMPP_DOMAIN := .Env.XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $XMPP_HIDDEN_DOMAIN := .Env.XMPP_HIDDEN_DOMAIN | default "hidden.meet.jitsi" -}}
{{ $XMPP_PORT := .Env.XMPP_PORT | default "5222" -}}
{{ $XMPP_SERVER := .Env.XMPP_SERVER | default "xmpp.meet.jitsi" -}}
{{ $MAX_SSRCS_PER_USER := .Env.MAX_SSRCS_PER_USER | default "20" -}}
{{ $MAX_SSRC_GROUPS_PER_USER := .Env.MAX_SSRC_GROUPS_PER_USER | default $MAX_SSRCS_PER_USER -}}
{{ $TRUSTED_DOMAIN_LIST := .Env.JICOFO_TRUSTED_DOMAINS | default (or $ENABLE_RECORDING $ENABLE_TRANSCRIPTIONS | ternary $XMPP_HIDDEN_DOMAIN "") -}}
{{ $TRUSTED_DOMAINS := splitList "," $TRUSTED_DOMAIN_LIST | compact -}}
{{ $ENV := .Env }}
jicofo {
{{ if $JICOFO_ENABLE_AUTH }}
authentication {
enabled = true
// The type of authentication. Supported values are XMPP or JWT.
{{ if eq $JICOFO_AUTH_TYPE "jwt" }}
type = JWT
{{ else }}
type = XMPP
{{ end }}
login-url = "{{ $XMPP_DOMAIN }}"
enable-auto-login = {{ $ENABLE_AUTO_LOGIN }}
authentication-lifetime = {{ $JICOFO_AUTH_LIFETIME }}
}
{{ end }}
// Configuration related to jitsi-videobridge
bridge {
{{ if .Env.MAX_BRIDGE_PARTICIPANTS }}
max-bridge-participants = "{{ .Env.MAX_BRIDGE_PARTICIPANTS }}"
{{ end }}
{{ if .Env.BRIDGE_AVG_PARTICIPANT_STRESS }}
// The assumed average stress per participant. default is 0.01
average-participant-stress = "{{ .Env.BRIDGE_AVG_PARTICIPANT_STRESS }}"
{{ end }}
{{ if .Env.BRIDGE_STRESS_THRESHOLD }}
// The stress level above which a bridge is considered overstressed. 0.8 is the default value
stress-threshold = "{{ .Env.BRIDGE_STRESS_THRESHOLD }}"
{{ end }}
{{ if $ENABLE_VISITORS }}
selection-strategy = VisitorSelectionStrategy
visitor-selection-strategy = RegionBasedBridgeSelectionStrategy
participant-selection-strategy = RegionBasedBridgeSelectionStrategy
topology-strategy = VisitorTopologyStrategy
{{ else }}
{{ if .Env.OCTO_BRIDGE_SELECTION_STRATEGY }}
selection-strategy = "{{ .Env.OCTO_BRIDGE_SELECTION_STRATEGY }}"
{{ end }}
{{ end }}
{{ if .Env.JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS }}
health-checks {
enabled = {{ .Env.JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS | toBool }}
use-presence = {{ $HEALTH_CHECKS_USE_PRESENCE }}
}
{{ end }}
{{ if .Env.JICOFO_ENABLE_ICE_FAILURE_DETECTION }}
ice-failure-detection {
enabled = {{ .Env.JICOFO_ENABLE_ICE_FAILURE_DETECTION | toBool }}
interval = {{ $ICE_FAILURE_INTERVAL }} seconds
min-endpoints = {{ $ICE_FAILURE_MIN_ENDPOINTS }}
threshold = {{ $ICE_FAILURE_THRESHOLD }}
}
{{ end }}
{{ if .Env.JICOFO_ENABLE_LOAD_REDISTRIBUTION }}
load-redistribution {
enabled = {{ .Env.JICOFO_ENABLE_LOAD_REDISTRIBUTION | toBool }}
}
{{ end }}
{{ if $ENABLE_JVB_XMPP_SERVER }}
brewery-jid = "{{ $JVB_BREWERY_MUC }}@{{ $JVB_XMPP_INTERNAL_MUC_DOMAIN }}"
{{ else }}
brewery-jid = "{{ $JVB_BREWERY_MUC }}@{{ $XMPP_INTERNAL_MUC_DOMAIN }}"
{{ end }}
{{ if .Env.JICOFO_BRIDGE_REGION_GROUPS }}
region-groups = [{{ .Env.JICOFO_BRIDGE_REGION_GROUPS }}]
{{ end }}
}
// Configure the codecs and RTP extensions to be used in the offer sent to clients.
codec {
video {
{{ if .Env.ENABLE_CODEC_VP8 }}
vp8 {
enabled = {{ .Env.ENABLE_CODEC_VP8 | toBool }}
}
{{ end }}
{{ if .Env.ENABLE_CODEC_VP9 }}
vp9 {
enabled = {{ .Env.ENABLE_CODEC_VP9 | toBool }}
}
{{ end }}
{{ if .Env.ENABLE_CODEC_AV1 }}
av1 {
enabled = {{ .Env.ENABLE_CODEC_AV1 | toBool }}
}
{{ end }}
{{ if .Env.ENABLE_CODEC_H264 }}
h264 {
enabled = {{ .Env.ENABLE_CODEC_H264 | toBool }}
}
{{ end }}
}
audio {
{{ if .Env.ENABLE_CODEC_OPUS_RED }}
opus {
red {
enabled = {{ .Env.ENABLE_CODEC_OPUS_RED | toBool }}
}
}
{{ end }}
}
rtp-extensions {
video-layers-allocation {
enabled = {{ .Env.ENABLE_VLA | default "0" | toBool }}
}
}
}
conference {
{{ if .Env.ENABLE_AUTO_OWNER }}
enable-auto-owner = {{ .Env.ENABLE_AUTO_OWNER | toBool }}
{{ end }}
{{ if .Env.ENABLE_MODERATOR_CHECKS }}
enable-moderator-checks = {{ .Env.ENABLE_MODERATOR_CHECKS | toBool }}
{{ end }}
{{ if .Env.JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT }}
initial-timeout = "{{ .Env.JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT }}"
{{ end }}
max-ssrcs-per-user = "{{ $MAX_SSRCS_PER_USER }}"
max-ssrc-groups-per-user = "{{ $MAX_SSRC_GROUPS_PER_USER }}"
{{ if .Env.JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT }}
single-participant-timeout = "{{ .Env.JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT }}"
{{ end }}
{{ if .Env.JICOFO_CONF_SOURCE_SIGNALING_DELAYS }}
source-signaling-delays = {{ .Env.JICOFO_CONF_SOURCE_SIGNALING_DELAYS }}
{{ end }}
{{ if .Env.JICOFO_CONF_MAX_AUDIO_SENDERS }}
max-audio-senders = {{ .Env.JICOFO_CONF_MAX_AUDIO_SENDERS }}
{{ end }}
{{ if .Env.JICOFO_CONF_MAX_VIDEO_SENDERS }}
max-video-senders = {{ .Env.JICOFO_CONF_MAX_VIDEO_SENDERS }}
{{ end }}
{{ if .Env.JICOFO_CONF_STRIP_SIMULCAST }}
strip-simulcast = {{ .Env.JICOFO_CONF_STRIP_SIMULCAST | toBool }}
{{ end }}
{{ if .Env.JICOFO_CONF_SSRC_REWRITING }}
use-ssrc-rewriting = {{ .Env.JICOFO_CONF_SSRC_REWRITING | toBool }}
{{ end }}
{{ if .Env.JICOFO_MULTI_STREAM_BACKWARD_COMPAT }}
enable-multi-stream-backward-compat = {{ .Env.JICOFO_MULTI_STREAM_BACKWARD_COMPAT | toBool }}
{{ end }}
{{ if $ENABLE_SHARED_DOCUMENT_RANDOM_NAME }}
shared-document {
use-random-name = {{ $ENABLE_SHARED_DOCUMENT_RANDOM_NAME }}
}
{{ end }}
{{ if .Env.JICOFO_RESTART_REQUEST_MAX }}
restart-request-rate-limits {
max-requests = {{ .Env.JICOFO_RESTART_REQUEST_MAX }}
interval = {{ $RESTART_REQUEST_INTERVAL }} seconds
}
{{ end }}
}
{{ if .Env.JICOFO_ENABLE_HEALTH_CHECKS }}
// Configuration for the internal health checks performed by jicofo.
health {
// Whether to perform health checks.
enabled = {{ .Env.JICOFO_ENABLE_HEALTH_CHECKS | toBool }}
}
{{ end }}
{{ if $ENABLE_RECORDING }}
jibri {
brewery-jid = "{{ $JIBRI_BREWERY_MUC }}@{{ $XMPP_INTERNAL_MUC_DOMAIN }}"
{{ if .Env.JIBRI_REQUEST_RETRIES }}
num-retries = "{{ .Env.JIBRI_REQUEST_RETRIES }}"
{{ end }}
pending-timeout = "{{ $JIBRI_PENDING_TIMEOUT }}"
}
{{ end }}
{{ if .Env.JIBRI_SIP_BREWERY_MUC }}
jibri-sip {
brewery-jid = "{{ .Env.JIBRI_SIP_BREWERY_MUC }}"
}
{{ end }}
{{ if or .Env.JIGASI_SIP_URI $ENABLE_TRANSCRIPTIONS }}
jigasi {
brewery-jid = "{{ $JIGASI_BREWERY_MUC }}@{{ $XMPP_INTERNAL_MUC_DOMAIN }}"
}
{{ end }}
{{ if .Env.JICOFO_OCTO_REGION }}
local-region = "{{ .Env.JICOFO_OCTO_REGION }}"
{{ end }}
octo {
// Whether or not to use Octo. Note that when enabled, its use will be determined by
// $jicofo.bridge.selection-strategy. There's a corresponding flag in the JVB and these
// two MUST be in sync (otherwise bridges will crash because they won't know how to
// deal with octo channels).
enabled = {{ $ENABLE_OCTO }}
sctp-datachannels = {{ $ENABLE_OCTO_SCTP }}
}
{{ if $ENABLE_REST }}
rest {
host = "0.0.0.0"
}
{{ end }}
sctp {
enabled = {{ $ENABLE_SCTP }}
}
{{ if $ENABLE_VISITORS }}
visitors {
enabled = true
{{ if .Env.VISITORS_MAX_PARTICIPANTS }}
max-participants = {{ .Env.VISITORS_MAX_PARTICIPANTS }}
{{ end }}
{{ if $VISITORS_MAX_VISITORS_PER_NODE }}
max-visitors-per-node = {{ $VISITORS_MAX_VISITORS_PER_NODE }}
{{ end }}
require-muc-config-flag = {{ $VISITORS_REQUIRE_MUC_CONFIG }}
}
{{ end }}
xmpp {
{{ if $ENABLE_VISITORS }}
{{ if $.Env.VISITORS_XMPP_SERVER }}
visitors {
{{ range $index, $element := $VISITORS_XMPP_SERVERS -}}
{{ $SERVER := splitn ":" 2 $element }}
v{{ $index }} {
enabled = true
conference-service = {{ $VISITORS_MUC_PREFIX }}.v{{ $index }}.{{ $VISITORS_XMPP_DOMAIN }}
hostname = {{ $SERVER._0 }}
{{ $DEFAULT_PORT := add $VISITORS_XMPP_PORT $index }}
port = {{ $SERVER._1 | default $DEFAULT_PORT }}
domain = "{{ $VISITORS_XMPP_AUTH_DOMAIN }}"
xmpp-domain = v{{ $index }}.{{ $VISITORS_XMPP_DOMAIN }}
password = "{{ $ENV.JICOFO_AUTH_PASSWORD }}"
disable-certificate-verification = true
}
{{ end }}
}
{{ end }}
{{ end }}
client {
enabled = true
hostname = "{{ $XMPP_SERVER }}"
port = "{{ $XMPP_PORT }}"
domain = "{{ $XMPP_AUTH_DOMAIN }}"
xmpp-domain = "{{ $XMPP_DOMAIN }}"
username = "focus"
password = "{{ .Env.JICOFO_AUTH_PASSWORD }}"
conference-muc-jid = "{{ $XMPP_MUC_DOMAIN }}"
client-proxy = "focus.{{ $XMPP_DOMAIN }}"
disable-certificate-verification = true
}
{{ if $ENABLE_JVB_XMPP_SERVER }}
service {
enabled = true
hostname = "{{ $JVB_XMPP_SERVER }}"
port = "{{ $JVB_XMPP_PORT }}"
domain = "{{ $JVB_XMPP_AUTH_DOMAIN }}"
username = "focus"
password = "{{ .Env.JICOFO_AUTH_PASSWORD }}"
disable-certificate-verification = true
}
{{ end }}
trusted-domains = [ {{ range $index, $element := $TRUSTED_DOMAINS }}{{ if gt $index 0 }},{{ end }}"{{ $element }}"{{ end}} ]
}
}
include "custom-jicofo.conf"

View File

@@ -0,0 +1,15 @@
{{ if .Env.SENTRY_DSN | toBool }}
handlers=java.util.logging.ConsoleHandler,io.sentry.jul.SentryHandler
{{ else }}
handlers= java.util.logging.ConsoleHandler
{{ end }}
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
org.jitsi.utils.logging2.JitsiLogFormatter.programname=Jicofo
.level=INFO
io.sentry.jul.SentryHandler.level=WARNING
# Enable debug packets logging
#org.jitsi.impl.protocol.xmpp.level=FINE

View File

@@ -0,0 +1,22 @@
#!/usr/bin/with-contenv bash
export SENTRY_RELEASE="${SENTRY_RELEASE:-$(apt-cache policy jicofo | sed -n '/Installed/p' | sed -e 's/[^:]*: //')}"
if [[ -z $JICOFO_AUTH_PASSWORD ]]; then
echo 'FATAL ERROR: Jicofo auth password must be set'
exit 1
fi
OLD_JICOFO_AUTH_PASSWORD=passw0rd
if [[ "$JICOFO_AUTH_PASSWORD" == "$OLD_JICOFO_AUTH_PASSWORD" ]]; then
echo 'FATAL ERROR: Jicofo auth password must be changed, check the README'
exit 1
fi
# maintain backward compatibility with older variable
[ -z "${XMPP_HIDDEN_DOMAIN}" ] && export XMPP_HIDDEN_DOMAIN="$XMPP_RECORDER_DOMAIN"
tpl /defaults/logging.properties > /config/logging.properties
tpl /defaults/jicofo.conf > /config/jicofo.conf
chown -R jicofo:jitsi /config

View File

@@ -0,0 +1,11 @@
#!/usr/bin/with-contenv bash
JAVA_SYS_PROPS="-Djava.util.logging.config.file=/config/logging.properties -Dconfig.file=/config/jicofo.conf"
DAEMON=/usr/share/jicofo/jicofo.sh
DAEMON_DIR=/usr/share/jicofo/
JICOFO_CMD="exec $DAEMON"
[ -n "$JICOFO_LOG_FILE" ] && JICOFO_CMD="$JICOFO_CMD 2>&1 | tee $JICOFO_LOG_FILE"
exec s6-setuidgid jicofo /bin/bash -c "cd $DAEMON_DIR; JAVA_SYS_PROPS=\"$JAVA_SYS_PROPS\" $JICOFO_CMD"

View File

@@ -0,0 +1,3 @@
#!/bin/bash
curl --fail-with-body http://127.0.0.1:8888/about/health

View File

@@ -0,0 +1,70 @@
version: '3.5'
services:
# SIP gateway (audio)
jigasi:
image: jitsi/jigasi:${JITSI_IMAGE_VERSION:-stable-10590}
restart: ${RESTART_POLICY:-unless-stopped}
ports:
- '${JIGASI_PORT_MIN:-20000}-${JIGASI_PORT_MAX:-20050}:${JIGASI_PORT_MIN:-20000}-${JIGASI_PORT_MAX:-20050}/udp'
volumes:
- ${CONFIG}/jigasi:/config:Z
environment:
- AUTOSCALER_SIDECAR_KEY_FILE
- AUTOSCALER_SIDECAR_KEY_ID
- AUTOSCALER_SIDECAR_GROUP_NAME
- AUTOSCALER_SIDECAR_HOST_ID
- AUTOSCALER_SIDECAR_INSTANCE_ID
- AUTOSCALER_SIDECAR_PORT
- AUTOSCALER_SIDECAR_REGION
- AUTOSCALER_SIDECAR_SHUTDOWN_POLLING_INTERVAL
- AUTOSCALER_SIDECAR_STATS_POLLING_INTERVAL
- AUTOSCALER_URL
- BOSH_URL_PATTERN
- ENABLE_AUTH
- ENABLE_GUESTS
- ENABLE_VISITORS
- XMPP_AUTH_DOMAIN
- XMPP_GUEST_DOMAIN
- XMPP_MUC_DOMAIN
- XMPP_INTERNAL_MUC_DOMAIN
- XMPP_SERVER
- XMPP_PORT
- XMPP_DOMAIN
- PUBLIC_URL
- JIGASI_CONFIGURATION
- JIGASI_DISABLE_SIP
- JIGASI_ENABLE_REST
- JIGASI_JVB_TIMEOUT
- JIGASI_LOCAL_REGION
- JIGASI_LOG_FILE
- JIGASI_MODE=sip
- JIGASI_SIP_URI
- JIGASI_SIP_PASSWORD
- JIGASI_SIP_SERVER
- JIGASI_SIP_PORT
- JIGASI_SIP_TRANSPORT
- JIGASI_SIP_DEFAULT_ROOM
- JIGASI_STATS_ID
- JIGASI_XMPP_USER
- JIGASI_XMPP_PASSWORD
- JIGASI_BREWERY_MUC
- JIGASI_PORT_MIN
- JIGASI_PORT_MAX
- JIGASI_HEALTH_CHECK_SIP_URI
- JIGASI_HEALTH_CHECK_INTERVAL
- JIGASI_SIP_KEEP_ALIVE_METHOD
- JIGASI_ENABLE_SDES_SRTP
- JIGASI_VISITORS_QUEUE_SERVICE_URL
- JIGASI_VISITORS_QUEUE_SERVICE_PRIVATE_KEY_PATH
- JIGASI_VISITORS_QUEUE_SERVICE_PRIVATE_KEY_ID
- SHUTDOWN_REST_ENABLED
- SENTRY_DSN="${JIGASI_SENTRY_DSN:-0}"
- SENTRY_ENVIRONMENT
- SENTRY_RELEASE
- TZ
- USE_TRANSLATOR_IN_CONFERENCE
depends_on:
- prosody
networks:
meet.jitsi:

View File

@@ -0,0 +1,19 @@
ARG JITSI_REPO=jitsi
ARG BASE_TAG=latest
FROM ${JITSI_REPO}/base-java:${BASE_TAG}
LABEL org.opencontainers.image.title="Jitsi Gateway to SIP (jigasi)"
LABEL org.opencontainers.image.description="Server-side application that allows regular SIP clients to join conferences."
LABEL org.opencontainers.image.url="https://github.com/jitsi/jigasi"
LABEL org.opencontainers.image.source="https://github.com/jitsi/docker-jitsi-meet"
LABEL org.opencontainers.image.documentation="https://jitsi.github.io/handbook/"
ENV GOOGLE_APPLICATION_CREDENTIALS=/config/key.json
RUN apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y jigasi jq jitsi-autoscaler-sidecar && \
apt-cleanup
COPY rootfs/ /
VOLUME ["/config", "/tmp/transcripts"]

View File

@@ -0,0 +1,19 @@
{{ $SHUTDOWN_POLLING_INTERVAL := .Env.AUTOSCALER_SIDECAR_SHUTDOWN_POLLING_INTERVAL | default "60" -}}
{{ $STATS_POLLING_INTERVAL := .Env.AUTOSCALER_SIDECAR_STATS_POLLING_INTERVAL | default "30" -}}
{{ $JIGASI_STATS_PORT := .Env.JIGASI_STATS_PORT | default "8788" -}}
export SHUTDOWN_POLLING_INTERVAL={{ $SHUTDOWN_POLLING_INTERVAL }}
export STATS_POLLING_INTERVAL={{ $STATS_POLLING_INTERVAL }}
export PORT={{ .Env.AUTOSCALER_SIDECAR_PORT }}
export GRACEFUL_SHUTDOWN_SCRIPT="/usr/share/jigasi/graceful_shutdown.sh"
export TERMINATE_SCRIPT="/opt/jitsi/shutdown.sh"
export ENABLE_REPORT_STATS=true
export POLLING_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/poll"
export STATUS_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/status"
export SHUTDOWN_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/shutdown"
export STATS_RETRIEVE_URL="http://localhost:{{ $JIGASI_STATS_PORT }}/about/stats"
export STATS_REPORT_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/stats"
export ASAP_SIGNING_KEY_FILE="{{ .Env.AUTOSCALER_SIDECAR_KEY_FILE }}"
export ASAP_JWT_KID="{{ .Env.AUTOSCALER_SIDECAR_KEY_ID }}"
export INSTANCE_TYPE="jigasi"
export INSTANCE_ID="{{ .Env.AUTOSCALER_SIDECAR_INSTANCE_ID }}"
export INSTANCE_METADATA='{"environment":"{{ .Env.XMPP_ENV_NAME }}","region":"{{ .Env.AUTOSCALER_SIDECAR_REGION }}","group":"{{ .Env.AUTOSCALER_SIDECAR_GROUP_NAME }}","name":"{{ .Env.JIGASI_INSTANCE_ID }}","version":"{{ .Env.JIGASI_VERSION }}","privateIp":"{{ .Env.LOCAL_ADDRESS }}","hostId":"{{ .Env.AUTOSCALER_SIDECAR_HOST_ID }}"}'

View File

@@ -0,0 +1,20 @@
{{ if .Env.SENTRY_DSN | toBool }}
handlers=java.util.logging.ConsoleHandler,io.sentry.jul.SentryHandler
{{ else }}
handlers=java.util.logging.ConsoleHandler
{{ end }}
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
.level=INFO
net.sf.level=SEVERE
net.java.sip.communicator.plugin.reconnectplugin.level=FINE
org.ice4j.level=SEVERE
org.jitsi.impl.neomedia.level=SEVERE
io.sentry.jul.SentryHandler.level=WARNING
# Do not worry about missing strings
net.java.sip.communicator.service.resources.AbstractResourcesService.level=SEVERE
#net.java.sip.communicator.service.protocol.level=ALL

View File

@@ -0,0 +1,80 @@
{{ $JIGASI_JVB_TIMEOUT := .Env.JIGASI_JVB_TIMEOUT | default "30000" -}}
{{ $JIGASI_LOCAL_REGION := .Env.JIGASI_LOCAL_REGION | default "" -}}
{{ $BOSH_URL_PATTERN := .Env.BOSH_URL_PATTERN | default "" -}}
{{ $XMPP_MUC_DOMAIN := .Env.XMPP_MUC_DOMAIN | default "muc.meet.jitsi" -}}
{{ $XMPP_SERVER := .Env.XMPP_SERVER | default "xmpp.meet.jitsi" -}}
{{ $XMPP_SERVERS := splitList "," $XMPP_SERVER | compact -}}
{{ $XMPP_PORT := .Env.XMPP_PORT | default "5222" -}}
{{ $XMPP_SERVER_ADDRESS := splitn ":" 3 ($XMPP_SERVERS | first) }}
{{ $SHUTDOWN_REST_ENABLED := .Env.SHUTDOWN_REST_ENABLED | default "false" | toBool -}}
{{ $TRUSTED_DOMAIN_LIST := .Env.JIGASI_TRUSTED_DOMAINS | default "" -}}
{{ $TRUSTED_DOMAINS := splitList "," $TRUSTED_DOMAIN_LIST | compact -}}
{{ $ENABLE_REST := .Env.JIGASI_ENABLE_REST | default "false" | toBool -}}
net.java.sip.communicator.impl.protocol.SingleCallInProgressPolicy.enabled=false
# Adjust opus encoder complexity
net.java.sip.communicator.impl.neomedia.codec.audio.opus.encoder.COMPLEXITY=10
# Disables packet logging
net.java.sip.communicator.packetlogging.PACKET_LOGGING_ENABLED=false
# Control REST Shutdown
org.jitsi.jigasi.ENABLE_REST_SHUTDOWN={{ $SHUTDOWN_REST_ENABLED }}
org.jitsi.jigasi.BREWERY_ENABLED=true
org.jitsi.jigasi.MUC_JOIN_TIMEOUT=10
org.jitsi.jigasi.HEALTH_CHECK_SIP_URI={{ .Env.JIGASI_HEALTH_CHECK_SIP_URI | default "" }}
org.jitsi.jigasi.HEALTH_CHECK_INTERVAL={{ .Env.JIGASI_HEALTH_CHECK_INTERVAL | default "300000" }}
org.jitsi.jigasi.HEALTH_CHECK_TIMEOUT=600000
org.jitsi.jigasi.xmpp.acc.IS_SERVER_OVERRIDDEN=true
org.jitsi.jigasi.xmpp.acc.SERVER_ADDRESS={{ $XMPP_SERVER_ADDRESS._0 }}
org.jitsi.jigasi.xmpp.acc.SERVER_PORT={{ $XMPP_SERVER_ADDRESS._1 | default $XMPP_PORT }}
org.jitsi.jigasi.xmpp.acc.VIDEO_CALLING_DISABLED=true
org.jitsi.jigasi.xmpp.acc.JINGLE_NODES_ENABLED=false
org.jitsi.jigasi.xmpp.acc.AUTO_DISCOVER_STUN=false
org.jitsi.jigasi.xmpp.acc.USE_DEFAULT_STUN_SERVER=false
org.jitsi.jigasi.xmpp.acc.IM_DISABLED=true
org.jitsi.jigasi.xmpp.acc.SERVER_STORED_INFO_DISABLED=true
org.jitsi.jigasi.xmpp.acc.IS_FILE_TRANSFER_DISABLED=true
# Activate this property if you are using self-signed certificates or other
# type of non-trusted certicates. In this mode your service trust in the
# remote certificates always.
net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED=true
{{ if .Env.JIGASI_SIP_DEFAULT_ROOM }}
org.jitsi.jigasi.DEFAULT_JVB_ROOM_NAME={{ .Env.JIGASI_SIP_DEFAULT_ROOM }}
{{ end }}
org.jitsi.jigasi.MUC_SERVICE_ADDRESS={{ $XMPP_MUC_DOMAIN }}
# when checking other participants whether they are jibri/jigasi we can also check the the domain they use for connecting
{{ if $TRUSTED_DOMAIN_LIST }}
org.jitsi.jigasi.TRUSTED_DOMAINS=[ {{ range $index, $element := $TRUSTED_DOMAINS }}{{ if gt $index 0 }},{{ end }}"{{ $element }}"{{ end}} ]
{{ end }}
org.jitsi.jigasi.JVB_INVITE_TIMEOUT={{ $JIGASI_JVB_TIMEOUT }}
{{ if $JIGASI_LOCAL_REGION }}
org.jitsi.jigasi.LOCAL_REGION={{ $JIGASI_LOCAL_REGION }}
{{ end }}
{{ if $BOSH_URL_PATTERN }}
org.jitsi.jigasi.xmpp.acc.BOSH_URL_PATTERN={{ $BOSH_URL_PATTERN }}
{{ end }}
{{ if $ENABLE_REST }}
org.jitsi.jigasi.rest.jetty.host=0.0.0.0
{{ end }}
{{ if .Env.JIGASI_STATS_ID -}}
org.jitsi.jigasi.STATS_ID={{ .Env.JIGASI_STATS_ID }}
{{- end }}
{{ if .Env.JIGASI_CONFIGURATION -}}
{{ join "\n" (splitList "," .Env.JIGASI_CONFIGURATION | compact) }}
{{ end -}}

View File

@@ -0,0 +1,98 @@
{{ $ENABLE_VISITORS := .Env.ENABLE_VISITORS | default "0" | toBool -}}
{{ $JIGASI_SIP_PASSWORD := .Env.JIGASI_SIP_PASSWORD | default "replaceme" -}}
{{ $JIGASI_XMPP_USER := .Env.JIGASI_XMPP_USER | default "jigasi" -}}
{{ $XMPP_AUTH_DOMAIN := .Env.XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $XMPP_DOMAIN := .Env.XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $XMPP_GUEST_DOMAIN := .Env.XMPP_GUEST_DOMAIN | default "guest.meet.jitsi" -}}
{{ $USE_TRANSLATOR_IN_CONFERENCE := .Env.USE_TRANSLATOR_IN_CONFERENCE | default "0" | toBool -}}
org.jitsi.jigasi.ENABLE_SIP=true
# SIP account
net.java.sip.communicator.impl.protocol.sip.acc1=acc1
{{ if .Env.JIGASI_SIP_SERVER }}
net.java.sip.communicator.impl.protocol.sip.acc1.PROXY_ADDRESS={{ .Env.JIGASI_SIP_SERVER }}
net.java.sip.communicator.impl.protocol.sip.acc1.PROXY_AUTO_CONFIG=false
net.java.sip.communicator.impl.protocol.sip.acc1.PROXY_PORT={{ .Env.JIGASI_SIP_PORT | default "5060" }}
net.java.sip.communicator.impl.protocol.sip.acc1.PREFERRED_TRANSPORT={{ .Env.JIGASI_SIP_TRANSPORT | default "UDP" }}
{{ end }}
{{ if .Env.JIGASI_ENABLE_SDES_SRTP | default "0" | toBool }}
net.java.sip.communicator.impl.protocol.sip.acc1.SAVP_OPTION=1
net.java.sip.communicator.impl.protocol.sip.acc1.DEFAULT_ENCRYPTION=true
net.java.sip.communicator.impl.protocol.sip.acc1.DEFAULT_SIPZRTP_ATTRIBUTE=false
net.java.sip.communicator.impl.protocol.sip.acc1.ENCRYPTION_PROTOCOL.ZRTP=0
net.java.sip.communicator.impl.protocol.sip.acc1.ENCRYPTION_PROTOCOL.SDES=1
net.java.sip.communicator.impl.protocol.sip.acc1.ENCRYPTION_PROTOCOL.DTLS-SRTP=0
net.java.sip.communicator.impl.protocol.sip.acc1.ENCRYPTION_PROTOCOL_STATUS.ZRTP=false
net.java.sip.communicator.impl.protocol.sip.acc1.ENCRYPTION_PROTOCOL_STATUS.SDES=true
net.java.sip.communicator.impl.protocol.sip.acc1.ENCRYPTION_PROTOCOL_STATUS.DTLS-SRTP=false
net.java.sip.communicator.impl.protocol.sip.acc1.SDES_CIPHER_SUITES=AES_CM_128_HMAC_SHA1_80,AES_CM_128_HMAC_SHA1_32
{{ end }}
net.java.sip.communicator.impl.protocol.sip.acc1.ACCOUNT_UID=SIP\:{{ .Env.JIGASI_SIP_URI }}
net.java.sip.communicator.impl.protocol.sip.acc1.PASSWORD={{ $JIGASI_SIP_PASSWORD | b64enc }}
net.java.sip.communicator.impl.protocol.sip.acc1.PROTOCOL_NAME=SIP
net.java.sip.communicator.impl.protocol.sip.acc1.SERVER_ADDRESS={{ .Env.JIGASI_SIP_SERVER }}
net.java.sip.communicator.impl.protocol.sip.acc1.USER_ID={{ .Env.JIGASI_SIP_URI }}
net.java.sip.communicator.impl.protocol.sip.acc1.KEEP_ALIVE_INTERVAL=25
net.java.sip.communicator.impl.protocol.sip.acc1.KEEP_ALIVE_METHOD={{ .Env.JIGASI_SIP_KEEP_ALIVE_METHOD | default "OPTIONS" }}
net.java.sip.communicator.impl.protocol.sip.acc1.VOICEMAIL_ENABLED=false
net.java.sip.communicator.impl.protocol.sip.acc1.JITSI_MEET_ROOM_HEADER_NAME=X-Room-Name
net.java.sip.communicator.impl.protocol.sip.acc1.JITSI_MEET_DOMAIN_BASE_HEADER_NAME=X-Domain-Base
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.AMR-WB/16000=750
# Temporarily disable G722, see: https://github.com/jitsi/docker-jitsi-meet/issues/1357
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.G722/8000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.GSM/8000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.H263-1998/90000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.H264/90000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.PCMA/8000=600
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.PCMU/8000=650
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.SILK/12000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.SILK/16000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.SILK/24000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.SILK/8000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.VP8/90000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.iLBC/8000=10
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.opus/48000=1000
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.red/90000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.speex/16000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.speex/32000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.speex/8000=0
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.telephone-event/8000=1
net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.ulpfec/90000=0
net.java.sip.communicator.impl.protocol.sip.acc1.OVERRIDE_ENCODINGS=true
net.java.sip.communicator.impl.protocol.sip.acc1.DOMAIN_BASE={{ $XMPP_DOMAIN }}
{{ if .Env.ENABLE_AUTH | default "0" | toBool }}
{{ if .Env.ENABLE_GUESTS | default "0" | toBool }}
org.jitsi.jigasi.xmpp.acc.USER_ID={{ $JIGASI_XMPP_USER }}@{{ $XMPP_GUEST_DOMAIN }}
org.jitsi.jigasi.xmpp.acc.ANONYMOUS_AUTH=true
{{ else }}
org.jitsi.jigasi.xmpp.acc.USER_ID={{ $JIGASI_XMPP_USER }}@{{ $XMPP_AUTH_DOMAIN }}
org.jitsi.jigasi.xmpp.acc.ANONYMOUS_AUTH=false
{{ end }}
org.jitsi.jigasi.xmpp.acc.PASS={{ .Env.JIGASI_XMPP_PASSWORD }}
org.jitsi.jigasi.xmpp.acc.ALLOW_NON_SECURE=true
{{ end }}
# forces sending presence on sip call hangup
net.java.sip.communicator.impl.protocol.jabber.FORCE_PRESENCE_ON_LEAVE=true
{{ if $USE_TRANSLATOR_IN_CONFERENCE }}
org.jitsi.jigasi.xmpp.acc.USE_TRANSLATOR_IN_CONFERENCE=true
net.java.sip.communicator.impl.protocol.sip.acc1.USE_TRANSLATOR_IN_CONFERENCE=true
# Should be enabled when using translator mode
net.java.sip.communicator.impl.neomedia.audioSystem.audiosilence.captureDevice_list=["AudioSilenceCaptureDevice:noTransferData"]
{{ end }}
{{ if $ENABLE_VISITORS -}}
org.jitsi.jigasi.ENABLE_SIP_VISITORS=true
{{ if .Env.JIGASI_VISITORS_QUEUE_SERVICE_URL -}}
org.jitsi.jigasi.VISITOR_QUEUE_SERVICE={{ .Env.JIGASI_VISITORS_QUEUE_SERVICE_URL }}
{{ end -}}
{{ if .Env.JIGASI_VISITORS_QUEUE_SERVICE_PRIVATE_KEY_PATH -}}
org.jitsi.jigasi.VISITOR_QUEUE_SERVICE_PRIVATE_KEY_PATH={{ .Env.JIGASI_VISITORS_QUEUE_SERVICE_PRIVATE_KEY_PATH }}
{{ end -}}
{{ if .Env.JIGASI_VISITORS_QUEUE_SERVICE_PRIVATE_KEY_ID -}}
org.jitsi.jigasi.VISITOR_QUEUE_SERVICE_PRIVATE_KEY_ID={{ .Env.JIGASI_VISITORS_QUEUE_SERVICE_PRIVATE_KEY_ID }}
{{ end -}}
{{ end -}}

View File

@@ -0,0 +1,71 @@
{{ $JIGASI_TRANSCRIBER_USER := .Env.JIGASI_TRANSCRIBER_USER | default "transcriber" -}}
{{ $JIGASI_TRANSCRIBER_FILTER_SILENCE := .Env.JIGASI_TRANSCRIBER_FILTER_SILENCE | default "0" | toBool -}}
{{ $XMPP_HIDDEN_DOMAIN := .Env.XMPP_HIDDEN_DOMAIN | default "hidden.meet.jitsi" -}}
{{ $JIGASI_TRANSCRIBER_ENABLE_SAVING := .Env.JIGASI_TRANSCRIBER_ENABLE_SAVING | default "1" | toBool -}}
{{ $JIGASI_TRANSCRIBER_ENABLE_TRANSLATION := .Env.JIGASI_TRANSCRIBER_ENABLE_TRANSLATION | default "0" | toBool -}}
org.jitsi.jigasi.ENABLE_SIP=false
org.jitsi.jigasi.xmpp.acc.USER_ID={{ $JIGASI_TRANSCRIBER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}
org.jitsi.jigasi.xmpp.acc.PASS={{ .Env.JIGASI_TRANSCRIBER_PASSWORD }}
org.jitsi.jigasi.xmpp.acc.ANONYMOUS_AUTH=false
org.jitsi.jigasi.xmpp.acc.ALLOW_NON_SECURE=true
# Transcription config
org.jitsi.jigasi.ENABLE_TRANSCRIPTION=true
{{ if $JIGASI_TRANSCRIBER_ENABLE_TRANSLATION -}}
org.jitsi.jigasi.transcription.ENABLE_TRANSLATION=true
{{ end -}}
{{ if $JIGASI_TRANSCRIBER_ENABLE_SAVING -}}
org.jitsi.jigasi.transcription.DIRECTORY=/tmp/transcripts
org.jitsi.jigasi.transcription.BASE_URL={{ .Env.PUBLIC_URL }}/transcripts
org.jitsi.jigasi.transcription.jetty.port=-1
org.jitsi.jigasi.transcription.ADVERTISE_URL={{ .Env.JIGASI_TRANSCRIBER_ADVERTISE_URL | default "false"}}
org.jitsi.jigasi.transcription.SAVE_JSON=false
org.jitsi.jigasi.transcription.SAVE_TXT=true
{{ end -}}
org.jitsi.jigasi.transcription.SEND_JSON=true
org.jitsi.jigasi.transcription.SEND_TXT={{ .Env.JIGASI_TRANSCRIBER_SEND_TXT | default "false"}}
org.jitsi.jigasi.transcription.RECORD_AUDIO={{ .Env.JIGASI_TRANSCRIBER_RECORD_AUDIO | default "false"}}
org.jitsi.jigasi.transcription.RECORD_AUDIO_FORMAT=wav
{{ if .Env.JIGASI_TRANSCRIBER_CUSTOM_SERVICE -}}
org.jitsi.jigasi.transcription.customService={{ .Env.JIGASI_TRANSCRIBER_CUSTOM_SERVICE }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_CUSTOM_TRANSLATION_SERVICE -}}
org.jitsi.jigasi.transcription.translationService={{ .Env.JIGASI_TRANSCRIBER_CUSTOM_TRANSLATION_SERVICE }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_LIBRETRANSLATE_URL -}}
org.jitsi.jigasi.transcription.libreTranslate.api_url={{ .Env.JIGASI_TRANSCRIBER_LIBRETRANSLATE_URL }}
{{ end -}}
{{ if $JIGASI_TRANSCRIBER_FILTER_SILENCE -}}
org.jitsi.jigasi.transcription.FILTER_SILENCE = true
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL -}}
org.jitsi.jigasi.transcription.remoteTranscriptionConfigUrl={{ .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL }}
{{ if .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL_KEY_PATH -}}
org.jitsi.jigasi.transcription.remoteTranscriptionConfigUrl.keyPath={{ .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL_KEY_PATH }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL_KEY_ID -}}
org.jitsi.jigasi.transcription.remoteTranscriptionConfigUrl.kid={{ .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL_KEY_ID }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL_AUD -}}
org.jitsi.jigasi.transcription.remoteTranscriptionConfigUrl.aud={{ .Env.JIGASI_TRANSCRIBER_REMOTE_CONFIG_URL_AUD }}
{{ end -}}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_OCI_REGION -}}
org.jitsi.jigasi.transcription.oci.websocketUrl=wss://realtime.aiservice.{{ .Env.JIGASI_TRANSCRIBER_OCI_REGION }}.oci.oraclecloud.com
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_OCI_COMPARTMENT -}}
org.jitsi.jigasi.transcription.oci.compartmentId={{ .Env.JIGASI_TRANSCRIBER_OCI_COMPARTMENT }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_WHISPER_URL -}}
org.jitsi.jigasi.transcription.whisper.websocket_url={{ .Env.JIGASI_TRANSCRIBER_WHISPER_URL }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_WHISPER_PRIVATE_KEY_NAME -}}
org.jitsi.jigasi.transcription.whisper.private_key_name={{ .Env.JIGASI_TRANSCRIBER_WHISPER_PRIVATE_KEY_NAME }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_WHISPER_PRIVATE_KEY -}}
org.jitsi.jigasi.transcription.whisper.private_key={{ .Env.JIGASI_TRANSCRIBER_WHISPER_PRIVATE_KEY }}
{{ end -}}
{{ if .Env.JIGASI_TRANSCRIBER_VOSK_URL -}}
org.jitsi.jigasi.transcription.vosk.websocket_url={{ .Env.JIGASI_TRANSCRIBER_VOSK_URL }}
{{ end -}}

View File

@@ -0,0 +1,68 @@
{{ $JIGASI_BREWERY_MUC := .Env.JIGASI_BREWERY_MUC | default "jigasibrewery" -}}
{{ $JIGASI_XMPP_USER := .Env.JIGASI_XMPP_USER | default "jigasi" -}}
{{ $JIGASI_XMPP_PASSWORD := .Env.JIGASI_XMPP_PASSWORD | default "replaceme" -}}
{{ $PUBLIC_URL_DOMAIN := .Env.PUBLIC_URL | default "https://localhost:8443" | trimPrefix "https://" | trimSuffix "/" -}}
{{ $XMPP_AUTH_DOMAIN := .Env.XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $XMPP_DOMAIN := .Env.XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $XMPP_INTERNAL_MUC_DOMAIN := .Env.XMPP_INTERNAL_MUC_DOMAIN | default "internal-muc.meet.jitsi" -}}
{{ $XMPP_PORT := .Env.XMPP_PORT | default "5222" -}}
{{ $XMPP_SERVER := .Env.XMPP_SERVER | default "xmpp.meet.jitsi" -}}
{{ $XMPP_SERVERS := splitList "," $XMPP_SERVER | compact -}}
# XMPP account used for control
{{ range $index, $element := $XMPP_SERVERS -}}
{{ $SERVER := splitn ":" 3 $element }}
{{ $ID := $SERVER._2 | default $index }}
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}=acc-{{ $ID }}
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.ACCOUNT_UID=Jabber:{{ $JIGASI_XMPP_USER }}@{{ $XMPP_AUTH_DOMAIN }}@{{ $ID }}
net.java.sip.communicator.plugin.reconnectplugin.ATLEAST_ONE_SUCCESSFUL_CONNECTION.Jabber\:{{ $JIGASI_XMPP_USER }}@{{ $XMPP_AUTH_DOMAIN }}=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.USER_ID={{ $JIGASI_XMPP_USER }}@{{ $XMPP_AUTH_DOMAIN }}
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IS_SERVER_OVERRIDDEN=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.SERVER_ADDRESS={{ $SERVER._0 }}
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.SERVER_PORT={{ $SERVER._1 | default $XMPP_PORT }}
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.ALLOW_NON_SECURE=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.PASSWORD={{ $JIGASI_XMPP_PASSWORD | b64enc }}
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.AUTO_GENERATE_RESOURCE=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.RESOURCE_PRIORITY=30
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.KEEP_ALIVE_METHOD=XEP-0199
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.KEEP_ALIVE_INTERVAL=20
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.CALLING_DISABLED=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.JINGLE_NODES_ENABLED=false
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IS_CARBON_DISABLED=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.DEFAULT_ENCRYPTION=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IS_USE_ICE=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IS_ACCOUNT_DISABLED=false
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IS_PREFERRED_PROTOCOL=false
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.AUTO_DISCOVER_JINGLE_NODES=false
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.PROTOCOL=Jabber
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IS_USE_UPNP=false
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IM_DISABLED=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.SERVER_STORED_INFO_DISABLED=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.IS_FILE_TRANSFER_DISABLED=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.USE_DEFAULT_STUN_SERVER=false
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.ENCRYPTION_PROTOCOL.DTLS-SRTP=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.ENCRYPTION_PROTOCOL_STATUS.DTLS-SRTP=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.VIDEO_CALLING_DISABLED=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.OVERRIDE_ENCODINGS=true
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.G722/8000=705
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.GSM/8000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.H263-1998/90000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.H264/90000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.PCMA/8000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.PCMU/8000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.SILK/12000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.SILK/16000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.SILK/24000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.SILK/8000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.VP8/90000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.iLBC/8000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.opus/48000=750
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.speex/16000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.speex/32000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.speex/8000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.Encodings.telephone-event/8000=0
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.BREWERY={{ $JIGASI_BREWERY_MUC }}@{{ $XMPP_INTERNAL_MUC_DOMAIN }}
net.java.sip.communicator.impl.protocol.jabber.acc-{{ $ID }}.DOMAIN_BASE={{ $PUBLIC_URL_DOMAIN }}
{{ end -}}
org.jitsi.jigasi.ALLOWED_JID={{ $JIGASI_BREWERY_MUC }}@{{ $XMPP_INTERNAL_MUC_DOMAIN }}

View File

@@ -0,0 +1,105 @@
#!/usr/bin/with-contenv bash
export SENTRY_RELEASE="${SENTRY_RELEASE:-$(apt-cache policy jigasi | sed -n '/Installed/p' | sed -e 's/[^:]*: //')}"
if [[ -z $JIGASI_XMPP_PASSWORD ]]; then
echo 'FATAL ERROR: Jigasi auth password must be set'
exit 1
fi
OLD_JIGASI_XMPP_PASSWORD=passw0rd
if [[ "$JIGASI_XMPP_PASSWORD" == "$OLD_JIGASI_XMPP_PASSWORD" ]]; then
echo 'FATAL ERROR: Jigasi auth password must be changed, check the README'
exit 1
fi
[ -z "$JIGASI_MODE" ] && JIGASI_MODE="sip"
JIGASI_MODE="$(echo $JIGASI_MODE | tr '[:upper:]' '[:lower:]')"
if [[ "$JIGASI_MODE" == "transcriber" ]]; then
# set random jigasi nickname for the instance if is not set
[ -z "${JIGASI_INSTANCE_ID}" ] && export JIGASI_INSTANCE_ID="transcriber-$(date +%N)"
fi
# set random jigasi nickname for the instance if is not set
[ -z "${JIGASI_INSTANCE_ID}" ] && export JIGASI_INSTANCE_ID="jigasi-$(date +%N)"
# set stats id for the instance
[ -z "${JIGASI_STATS_ID}" ] && export JIGASI_STATS_ID="$JIGASI_INSTANCE_ID"
# check for AUTOSCALER_URL, AUTOSCALER_SIDECAR_KEY_FILE and AUTOSCALER_SIDECAR_KEY_ID as indicator that sidecar should be enabled
if [ -n "$AUTOSCALER_URL" ]; then
if [ -z "$AUTOSCALER_SIDECAR_KEY_FILE" ]; then
export AUTOSCALER_SIDECAR_KEY_FILE="/etc/jitsi/autoscaler-sidecar/asap.pem"
fi
if [ -z "$AUTOSCALER_SIDECAR_KEY_ID" ]; then
# assume key id is equal to the base real path of the key file minus .pem
export AUTOSCALER_SIDECAR_KEY_ID="$(basename "$(realpath "$AUTOSCALER_SIDECAR_KEY_FILE")" | tr -d '.pem')"
fi
if [ -f "$AUTOSCALER_SIDECAR_KEY_FILE" ]; then
echo "AUTOSCALER_URL found, enabling autoscaler sidecar"
export JIGASI_VERSION="$(dpkg -s jigasi | grep Version | awk '{print $2}' | sed 's/..$//')"
[ -z "$AUTOSCALER_SIDECAR_PORT" ] && export AUTOSCALER_SIDECAR_PORT="6000"
[ -z "$AUTOSCALER_SIDECAR_INSTANCE_ID" ] && export AUTOSCALER_SIDECAR_INSTANCE_ID="$JIGASI_INSTANCE_ID"
[ -z "$AUTOSCALER_SIDECAR_REGION" ] && export AUTOSCALER_SIDECAR_REGION="docker"
[ -z "$AUTOSCALER_SIDECAR_GROUP_NAME" ] && export AUTOSCALER_SIDECAR_GROUP_NAME="docker-jigasi"
mkdir -p /etc/jitsi/autoscaler-sidecar
tpl /defaults/autoscaler-sidecar.config > /etc/jitsi/autoscaler-sidecar/config
else
echo "No key file at $AUTOSCALER_SIDECAR_KEY_FILE, leaving autoscaler sidecar disabled"
fi
else
echo "No AUTOSCALER_URL defined, leaving autoscaler sidecar disabled"
fi
# maintain backward compatibility with older variable
[ -z "${XMPP_HIDDEN_DOMAIN}" ] && export XMPP_HIDDEN_DOMAIN="$XMPP_RECORDER_DOMAIN"
tpl /defaults/logging.properties > /config/logging.properties
tpl /defaults/sip-communicator.properties > /config/sip-communicator.properties
tpl /defaults/xmpp-sip-communicator.properties >> /config/sip-communicator.properties
if [[ "$JIGASI_MODE" == "sip" ]]; then
tpl /defaults/sipserver-sip-communicator.properties >> /config/sip-communicator.properties
elif [[ "$JIGASI_MODE" == "transcriber" ]]; then
tpl /defaults/transcriber-sip-communicator.properties >> /config/sip-communicator.properties
mkdir -pm777 /tmp/transcripts
chown jigasi:jitsi /tmp/transcripts
# Create Google Cloud Credentials
if [[ -z $GC_PROJECT_ID || -z $GC_PRIVATE_KEY_ID || -z $GC_PRIVATE_KEY || -z $GC_CLIENT_EMAIL || -z $GC_CLIENT_ID || -z $GC_CLIENT_CERT_URL ]]; then
echo 'Transcriptions: One or more gcloud environment variables are undefined, skipping gcloud credentials file /config/key.json'
else
jq -n \
--arg GC_PROJECT_ID "$GC_PROJECT_ID" \
--arg GC_PRIVATE_KEY_ID "$GC_PRIVATE_KEY_ID" \
--arg GC_PRIVATE_KEY "$GC_PRIVATE_KEY" \
--arg GC_CLIENT_EMAIL "$GC_CLIENT_EMAIL" \
--arg GC_CLIENT_ID "$GC_CLIENT_ID" \
--arg GC_CLIENT_CERT_URL "$GC_CLIENT_CERT_URL" \
'{
type: "service_account",
project_id: $GC_PROJECT_ID,
private_key_id: $GC_PRIVATE_KEY_ID,
private_key: $GC_PRIVATE_KEY,
client_email: $GC_CLIENT_EMAIL,
client_id: $GC_CLIENT_ID,
auth_uri: "https://accounts.google.com/o/oauth2/auth",
token_uri: "https://oauth2.googleapis.com/token",
auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
client_x509_cert_url: $GC_CLIENT_CERT_URL
}' \
> /config/key.json
fi
fi
if [[ -f /config/custom-sip-communicator.properties ]]; then
cat /config/custom-sip-communicator.properties >> /config/sip-communicator.properties
fi
if [[ -f /config/custom-logging.properties ]]; then
cat /config/custom-logging.properties >> /config/logging.properties
fi

View File

@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash
if [[ -n "$AUTOSCALER_URL" ]] && [[ -f "/etc/jitsi/autoscaler-sidecar/config" ]]; then
DAEMON="/usr/bin/node /usr/share/jitsi-autoscaler-sidecar/app.js"
exec s6-setuidgid autoscaler-sidecar /bin/bash -c ". /etc/jitsi/autoscaler-sidecar/config && exec $DAEMON"
else
# if autoscaler-sidecar should not be started,
# prevent s6 from restarting this script again and again
s6-svc -O /var/run/s6/services/50-autoscaler-sidecar
fi

View File

@@ -0,0 +1,9 @@
#!/usr/bin/with-contenv bash
# When the jigasi is shutdown (or gracefully shutdown), it exits with code 0.
# In this case, we don't want S6 to restart the service. We want to stop all
# services and shutdown the container.
if [[ $1 -eq 0 ]]; then
/opt/jitsi/shutdown.sh
fi

View File

@@ -0,0 +1,11 @@
#!/usr/bin/with-contenv bash
JAVA_SYS_PROPS="-Djava.util.logging.config.file=/config/logging.properties"
DAEMON=/usr/share/jigasi/jigasi.sh
DAEMON_OPTS="--nocomponent=true --configdir=/ --configdirname=config --min-port=${JIGASI_PORT_MIN:-20000} --max-port=${JIGASI_PORT_MAX:-20050}"
JIGASI_CMD="JAVA_SYS_PROPS=\"$JAVA_SYS_PROPS\" exec $DAEMON $DAEMON_OPTS"
[ -n "$JIGASI_LOG_FILE" ] && JIGASI_CMD="$JIGASI_CMD 2>&1 | tee $JIGASI_LOG_FILE"
exec s6-setuidgid jigasi /bin/bash -c "$JIGASI_CMD"

View File

@@ -0,0 +1,11 @@
#!/usr/bin/with-contenv bash
if [ -n "$AUTOSCALER_URL" ]; then
# notify the sidecar of imminent shutdown
PORT=${AUTOSCALER_SIDECAR_PORT:-6000}
curl -d '{}' -v 0:$PORT/hook/v1/shutdown
sleep 10
fi
# shutdown everything
s6-svscanctl -t /var/run/s6/services

View File

@@ -0,0 +1,3 @@
#!/bin/bash
curl --fail-with-body http://127.0.0.1:8788/about/health

View File

@@ -0,0 +1,17 @@
ARG JITSI_REPO=jitsi
ARG BASE_TAG=latest
FROM ${JITSI_REPO}/base-java:${BASE_TAG}
LABEL org.opencontainers.image.title="Jitsi Videobridge (jvb)"
LABEL org.opencontainers.image.description="WebRTC compatible server designed to route video streams amongst participants in a conference."
LABEL org.opencontainers.image.url="https://jitsi.org/jitsi-videobridge/"
LABEL org.opencontainers.image.source="https://github.com/jitsi/docker-jitsi-meet"
LABEL org.opencontainers.image.documentation="https://jitsi.github.io/handbook/"
RUN apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y jitsi-videobridge2 jitsi-autoscaler-sidecar jq curl iproute2 dnsutils libpcap0.8 && \
apt-cleanup
COPY rootfs/ /
VOLUME /config

View File

@@ -0,0 +1,19 @@
{{ $JVB_COLIBRI_PORT := .Env.JVB_COLIBRI_PORT | default "8080" -}}
{{ $SHUTDOWN_POLLING_INTERVAL := .Env.AUTOSCALER_SIDECAR_SHUTDOWN_POLLING_INTERVAL | default "60" -}}
{{ $STATS_POLLING_INTERVAL := .Env.AUTOSCALER_SIDECAR_STATS_POLLING_INTERVAL | default "30" -}}
export SHUTDOWN_POLLING_INTERVAL={{ $SHUTDOWN_POLLING_INTERVAL }}
export STATS_POLLING_INTERVAL={{ $STATS_POLLING_INTERVAL }}
export PORT={{ .Env.AUTOSCALER_SIDECAR_PORT }}
export GRACEFUL_SHUTDOWN_SCRIPT="/usr/share/jitsi-videobridge/graceful_shutdown.sh"
export TERMINATE_SCRIPT="/opt/jitsi/shutdown.sh"
export ENABLE_REPORT_STATS=true
export POLLING_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/poll"
export STATUS_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/status"
export SHUTDOWN_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/shutdown"
export STATS_RETRIEVE_URL="http://localhost:{{ $JVB_COLIBRI_PORT }}/colibri/stats"
export STATS_REPORT_URL="{{ .Env.AUTOSCALER_URL }}/sidecar/stats"
export ASAP_SIGNING_KEY_FILE="{{ .Env.AUTOSCALER_SIDECAR_KEY_FILE }}"
export ASAP_JWT_KID="{{ .Env.AUTOSCALER_SIDECAR_KEY_ID }}"
export INSTANCE_TYPE="JVB"
export INSTANCE_ID="{{ .Env.AUTOSCALER_SIDECAR_INSTANCE_ID }}"
export INSTANCE_METADATA='{"environment":"{{ .Env.XMPP_ENV_NAME }}","region":"{{ .Env.AUTOSCALER_SIDECAR_REGION }}","group":"{{ .Env.AUTOSCALER_SIDECAR_GROUP_NAME }}","name":"{{ .Env.JVB_INSTANCE_ID }}","version":"{{ .Env.JVB_VERSION }}","privateIp":"{{ .Env.LOCAL_ADDRESS }}","publicIp":"{{ .Env.JVB_ADVERTISE_IPS }}","hostId":"{{ .Env.AUTOSCALER_SIDECAR_HOST_ID }}"}'

View File

@@ -0,0 +1,175 @@
{{ $COLIBRI_REST_ENABLED := .Env.COLIBRI_REST_ENABLED | default "false" | toBool -}}
{{ $DISABLE_AWS_HARVESTER := .Env.DISABLE_AWS_HARVESTER | default "false" | toBool -}}
{{ $DISABLE_XMPP := .Env.JVB_DISABLE_XMPP | default "0" | toBool -}}
{{ $ENABLE_COLIBRI_WEBSOCKET := .Env.ENABLE_COLIBRI_WEBSOCKET | default "0" | toBool -}}
{{ $ENABLE_OCTO := .Env.ENABLE_OCTO | default "0" | toBool -}}
{{ $ENABLE_SCTP := .Env.ENABLE_SCTP | default "1" | toBool -}}
{{ $ENABLE_JVB_XMPP_SERVER := .Env.ENABLE_JVB_XMPP_SERVER | default "0" | toBool }}
{{ $JVB_DISABLE_STUN := .Env.JVB_DISABLE_STUN | default "0" | toBool -}}
{{ $JVB_STUN_SERVERS := .Env.JVB_STUN_SERVERS | default "meet-jit-si-turnrelay.jitsi.net:443" -}}
{{ $JVB_AUTH_USER := .Env.JVB_AUTH_USER | default "jvb" -}}
{{ $JVB_BREWERY_MUC := .Env.JVB_BREWERY_MUC | default "jvbbrewery" -}}
{{ $JVB_CC_TRUST_BWE := .Env.JVB_CC_TRUST_BWE | default "true" | toBool -}}
{{ $JVB_MUC_NICKNAME := .Env.JVB_MUC_NICKNAME | default .Env.HOSTNAME -}}
{{ $JVB_ADVERTISE_PRIVATE_CANDIDATES := .Env.JVB_ADVERTISE_PRIVATE_CANDIDATES | default "true" | toBool -}}
{{ $JVB_ADVERTISE_IPS := .Env.JVB_ADVERTISE_IPS | default "" -}}
{{ $JVB_IPS := splitList "," $JVB_ADVERTISE_IPS | compact -}}
{{ $JVB_REQUIRE_VALID_ADDRESS := .Env.JVB_REQUIRE_VALID_ADDRESS | default "0" | toBool -}}
{{ $JVB_XMPP_AUTH_DOMAIN := .Env.JVB_XMPP_AUTH_DOMAIN | default "auth.jvb.meet.jitsi" -}}
{{ $JVB_XMPP_INTERNAL_MUC_DOMAIN := .Env.JVB_XMPP_INTERNAL_MUC_DOMAIN | default "muc.jvb.meet.jitsi" -}}
{{ $JVB_XMPP_PORT := .Env.JVB_XMPP_PORT | default "6222" -}}
{{ $JVB_XMPP_SERVER := .Env.JVB_XMPP_SERVER | default "xmpp.jvb.meet.jitsi" -}}
{{ $JVB_XMPP_SERVERS := splitList "," $JVB_XMPP_SERVER | compact -}}
{{ $PUBLIC_URL_DOMAIN := .Env.PUBLIC_URL | default "https://localhost:8443" | trimPrefix "https://" | trimSuffix "/" -}}
{{ $SHUTDOWN_REST_ENABLED := .Env.SHUTDOWN_REST_ENABLED | default "false" | toBool -}}
{{ $USE_USRSCTP := .Env.JVB_USE_USRSCTP | default "false" | toBool -}}
{{ $WS_DOMAIN := .Env.JVB_WS_DOMAIN | default $PUBLIC_URL_DOMAIN -}}
{{ $WS_SERVER_ID := .Env.JVB_WS_SERVER_ID | default .Env.JVB_WS_SERVER_ID_FALLBACK | default "default" -}}
{{ $WS_TLS := .Env.JVB_WS_TLS | default "1" | toBool -}}
{{ $XMPP_AUTH_DOMAIN := .Env.XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $XMPP_INTERNAL_MUC_DOMAIN := .Env.XMPP_INTERNAL_MUC_DOMAIN | default "internal-muc.meet.jitsi" -}}
{{ $XMPP_PORT := .Env.XMPP_PORT | default "5222" -}}
{{ $XMPP_SERVER := .Env.XMPP_SERVER | default "xmpp.meet.jitsi" -}}
{{ $XMPP_SERVERS := splitList "," $XMPP_SERVER | compact -}}
{{/* assign env from context, preserve during range when . is re-assigned */}}
{{ $ENV := .Env -}}
videobridge {
cc {
use-vla-target-bitrate = {{ .Env.ENABLE_VLA | default "0" | toBool }}
trust-bwe = {{ $JVB_CC_TRUST_BWE }}
}
ice {
udp {
port = {{ .Env.JVB_PORT | default 10000 }}
}
advertise-private-candidates = {{ $JVB_ADVERTISE_PRIVATE_CANDIDATES }}
}
apis {
{{ if not $DISABLE_XMPP -}}
xmpp-client {
configs {
{{ if $ENABLE_JVB_XMPP_SERVER }}
{{ range $index, $element := $JVB_XMPP_SERVERS -}}
{{ $SERVER := splitn ":" 2 $element }}
shard{{ $index }} {
HOSTNAME = "{{ $SERVER._0 }}"
PORT = "{{ $SERVER._1 | default $JVB_XMPP_PORT }}"
DOMAIN = "{{ $JVB_XMPP_AUTH_DOMAIN }}"
USERNAME = "{{ $JVB_AUTH_USER }}"
PASSWORD = "{{ $ENV.JVB_AUTH_PASSWORD }}"
MUC_JIDS = "{{ $JVB_BREWERY_MUC }}@{{ $JVB_XMPP_INTERNAL_MUC_DOMAIN }}"
MUC_NICKNAME = "{{ $JVB_MUC_NICKNAME }}"
DISABLE_CERTIFICATE_VERIFICATION = true
}
{{ end -}}
{{ else }}
{{ range $index, $element := $XMPP_SERVERS -}}
{{ $SERVER := splitn ":" 2 $element }}
shard{{ $index }} {
HOSTNAME = "{{ $SERVER._0 }}"
PORT = "{{ $SERVER._1 | default $XMPP_PORT }}"
DOMAIN = "{{ $XMPP_AUTH_DOMAIN }}"
USERNAME = "{{ $JVB_AUTH_USER }}"
PASSWORD = "{{ $ENV.JVB_AUTH_PASSWORD }}"
MUC_JIDS = "{{ $JVB_BREWERY_MUC }}@{{ $XMPP_INTERNAL_MUC_DOMAIN }}"
MUC_NICKNAME = "{{ $JVB_MUC_NICKNAME }}"
DISABLE_CERTIFICATE_VERIFICATION = true
}
{{ end -}}
{{ end -}}
}
}
{{ end -}}
rest {
enabled = {{ $COLIBRI_REST_ENABLED }}
}
}
rest {
shutdown {
enabled = {{ $SHUTDOWN_REST_ENABLED }}
}
}
sctp {
enabled = {{ $ENABLE_SCTP }}
use-usrsctp = {{ $USE_USRSCTP }}
}
stats {
enabled = true
}
websockets {
enabled = {{ $ENABLE_COLIBRI_WEBSOCKET }}
domain = "{{ $WS_DOMAIN }}"
tls = {{ $WS_TLS }}
server-id = "{{ $WS_SERVER_ID }}"
}
http-servers {
private {
host = 0.0.0.0
send-server-version = false
}
public {
host = 0.0.0.0
port = 9090
send-server-version = false
}
}
health {
require-valid-address = {{ $JVB_REQUIRE_VALID_ADDRESS }}
}
{{ if $ENABLE_OCTO -}}
relay {
enabled = true
region = "{{ .Env.JVB_OCTO_REGION | default "europe" }}"
relay-id = "{{ .Env.JVB_OCTO_RELAY_ID | default .Env.JVB_OCTO_BIND_ADDRESS }}"
}
{{ end -}}
}
jmt {
bwe {
estimator {
engine = "{{ .Env.BWE_ESTIMATOR_ENGINE | default "GoogleCc2" }}"
}
}
}
ice4j {
harvest {
mapping {
aws {
enabled = {{ not $DISABLE_AWS_HARVESTER }}
}
stun {
{{ if not $JVB_DISABLE_STUN -}}
addresses = [ "{{ join "\",\"" (splitList "," $JVB_STUN_SERVERS) }}" ]
{{ else -}}
enabled = false
{{ end -}}
}
static-mappings = [
{{ range $index, $element := $JVB_IPS -}}
{{ if contains "#" $element -}}
{{ $element_ip_port := splitn "#" 2 $element -}}
{
local-address = "{{ $ENV.LOCAL_ADDRESS }}"
public-address = "{{ $element_ip_port._0 }}"
local-port = {{ $ENV.JVB_PORT | default 10000 }}
public-port = {{ $element_ip_port._1 }}
name = "ip-{{ $index }}"
},
{{ else -}}
{
local-address = "{{ $ENV.LOCAL_ADDRESS }}"
public-address = "{{ $element }}"
name = "ip-{{ $index }}"
},
{{ end -}}
{{ end -}}
]
}
}
}
include "custom-jvb.conf"

View File

@@ -0,0 +1,12 @@
{{ if .Env.SENTRY_DSN | toBool }}
handlers=java.util.logging.ConsoleHandler,io.sentry.jul.SentryHandler
{{ else }}
handlers= java.util.logging.ConsoleHandler
{{ end }}
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
org.jitsi.utils.logging2.JitsiLogFormatter.programname=JVB
.level=INFO
io.sentry.jul.SentryHandler.level=WARNING

View File

@@ -0,0 +1,76 @@
#!/usr/bin/with-contenv bash
if [[ -z $JVB_DISABLE_XMPP ]]; then
if [[ -z $JVB_AUTH_PASSWORD ]]; then
echo 'FATAL ERROR: JVB auth password must be set'
exit 1
fi
OLD_JVB_AUTH_PASSWORD=passw0rd
if [[ "$JVB_AUTH_PASSWORD" == "$OLD_JVB_AUTH_PASSWORD" ]]; then
echo 'FATAL ERROR: JVB auth password must be changed, check the README'
exit 1
fi
[ -z "${XMPP_SERVER}" ] && export XMPP_SERVER=xmpp.meet.jitsi
# On environments like Swarm the IP address used by the default gateway need not be
# the one used for inter-container traffic. Use that one for our fallback ID.
XMPP_SERVER_IP=$(dig +short +search ${XMPP_SERVER})
export JVB_WS_SERVER_ID_FALLBACK=$(ip route get ${XMPP_SERVER_IP} | grep -oP '(?<=src ).*' | awk '{ print $1 '})
fi
# Migration from DOCKER_HOST_ADDRESS to JVB_ADVERTISE_IPS
if [[ -z "${JVB_ADVERTISE_IPS}" ]]; then
if [[ ! -z "${DOCKER_HOST_ADDRESS}" ]]; then
echo "WARNING: DOCKER_HOST_ADDRESS is deprecated, migrate to JVB_ADVERTISE_IPS"
export JVB_ADVERTISE_IPS=${DOCKER_HOST_ADDRESS}
fi
fi
# Local IP for the ice4j mapping harvester.
export LOCAL_ADDRESS=$(ip route get 1 | grep -oP '(?<=src ).*' | awk '{ print $1 '})
export SENTRY_RELEASE="${SENTRY_RELEASE:-$(apt-cache policy jitsi-videobridge2 | sed -n '/Installed/p' | sed -e 's/[^:]*: //')}"
if [[ -f /config/custom-sip-communicator.properties ]]; then
cat /config/custom-sip-communicator.properties > /config/sip-communicator.properties
fi
# set random jvb nickname for the instance if is not set
[ -z "${JVB_INSTANCE_ID}" ] && export JVB_INSTANCE_ID="jvb-$(date +%N)"
# check for AUTOSCALER_URL, AUTOSCALER_SIDECAR_KEY_FILE and AUTOSCALER_SIDECAR_KEY_ID as indicator that sidecar should be enabled
if [ -n "$AUTOSCALER_URL" ]; then
if [ -z "$AUTOSCALER_SIDECAR_KEY_FILE" ]; then
export AUTOSCALER_SIDECAR_KEY_FILE="/etc/jitsi/autoscaler-sidecar/asap.pem"
fi
if [ -z "$AUTOSCALER_SIDECAR_KEY_ID" ]; then
# assume key id is equal to the base real path of the key file minus .pem
export AUTOSCALER_SIDECAR_KEY_ID="$(basename "$(realpath "$AUTOSCALER_SIDECAR_KEY_FILE")" | tr -d '.pem')"
fi
if [ -f "$AUTOSCALER_SIDECAR_KEY_FILE" ]; then
echo "AUTOSCALER_URL found, enabling autoscaler sidecar"
export JVB_VERSION="$(dpkg -s jitsi-videobridge2 | grep Version | awk '{print $2}' | sed 's/..$//')"
[ -z "$AUTOSCALER_SIDECAR_PORT" ] && export AUTOSCALER_SIDECAR_PORT="6000"
[ -z "$JIBRI_WEBHOOK_SUBSCRIBERS" ] && export JIBRI_WEBHOOK_SUBSCRIBERS="http://localhost:$AUTOSCALER_SIDECAR_PORT/hook"
[ -z "$AUTOSCALER_SIDECAR_INSTANCE_ID" ] && export AUTOSCALER_SIDECAR_INSTANCE_ID="$JVB_INSTANCE_ID"
[ -z "$AUTOSCALER_SIDECAR_REGION" ] && export AUTOSCALER_SIDECAR_REGION="docker"
[ -z "$AUTOSCALER_SIDECAR_GROUP_NAME" ] && export AUTOSCALER_SIDECAR_GROUP_NAME="docker-jvb"
mkdir -p /etc/jitsi/autoscaler-sidecar
tpl /defaults/autoscaler-sidecar.config > /etc/jitsi/autoscaler-sidecar/config
else
echo "No key file at $AUTOSCALER_SIDECAR_KEY_FILE, leaving autoscaler sidecar disabled"
fi
else
echo "No AUTOSCALER_URL defined, leaving autoscaler sidecar disabled"
fi
tpl /defaults/logging.properties > /config/logging.properties
tpl /defaults/jvb.conf > /config/jvb.conf
chown -R jvb:jitsi /config

View File

@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash
if [[ -n "$AUTOSCALER_URL" ]] && [[ -f "/etc/jitsi/autoscaler-sidecar/config" ]]; then
DAEMON="/usr/bin/node /usr/share/jitsi-autoscaler-sidecar/app.js"
exec s6-setuidgid autoscaler-sidecar /bin/bash -c ". /etc/jitsi/autoscaler-sidecar/config && exec $DAEMON"
else
# if autoscaler-sidecar should not be started,
# prevent s6 from restarting this script again and again
s6-svc -O /var/run/s6/services/50-autoscaler-sidecar
fi

View File

@@ -0,0 +1,9 @@
#!/usr/bin/with-contenv bash
# When the jvb is shutdown (or gracefully shutdown), it exits with code 0.
# In this case, we don't want S6 to restart the service. We want to stop all
# services and shutdown the container.
if [[ $1 -eq 0 ]]; then
/opt/jitsi/shutdown.sh
fi

View File

@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash
export JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/ -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=config -Djava.util.logging.config.file=/config/logging.properties -Dconfig.file=/config/jvb.conf"
DAEMON=/usr/share/jitsi-videobridge/jvb.sh
JVB_CMD="exec $DAEMON"
[ -n "$JVB_LOG_FILE" ] && JVB_CMD="$JVB_CMD 2>&1 | tee $JVB_LOG_FILE"
exec s6-setuidgid jvb /bin/bash -c "$JVB_CMD"

View File

@@ -0,0 +1,11 @@
#!/usr/bin/with-contenv bash
if [ -n "$AUTOSCALER_URL" ]; then
# notify the sidecar of imminent shutdown
PORT=${AUTOSCALER_SIDECAR_PORT:-6000}
curl -d '{}' -v 0:$PORT/hook/v1/shutdown
sleep 10
fi
# shutdown everything
s6-svscanctl -t /var/run/s6/services

View File

@@ -0,0 +1,3 @@
#!/bin/bash
curl --fail-with-body http://127.0.0.1:8080/about/health

View File

@@ -0,0 +1,26 @@
version: '3.5'
services:
# Log Analyser: used for setting up a log analysis system for visualization, log collection and log processing.
loki:
image: grafana/loki:3.0.0
command: -config.file=/conf/loki-config.yaml
volumes:
- ./log-analyser/loki/data:/data
- ./log-analyser/loki/conf:/conf
ports:
- "3100:3100"
networks:
meet.jitsi:
otel:
image: otel/opentelemetry-collector-contrib:0.130.0
user: "0" # required for reading docker container logs
volumes:
- ./log-analyser/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
- ./log-analyser/jitsi-logs/:/tmp/jitsi-logs/
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock
networks:
meet.jitsi:

View File

@@ -0,0 +1,80 @@
# JITSI MEET LOG ANALYSER - Grafana Loki and OpenTelemetry Integration
Welcome to the Grafana Loki and OpenTelemetry integration project! This repository provides a simple and effective setup for log management and analysis using Docker, Grafana Loki, and OpenTelemetry.
Currently this is an in-progress GSoC Summer of Code project and so the instructions may change before being finalized. Please treat all this as alpha code.
## Overview
This project demonstrates how to configure and use Grafana Loki with OpenTelemetry to collect, parse, and visualize log data from Jitsi Meet components. It includes:
- A Docker Compose setup (`log-analyser.yml`) for Loki and OpenTelemetry Collector.
- A Docker Compose setup (`grafana.yml`) for Grafana.
- A unified Docker Compose command to start all services.
- Instructions to set up and access Grafana with Loki as a data source.
## Getting Started
### Prerequisites
- Docker
- Docker Compose
### Setup
1. **Clone the repository:**
```bash
git clone https://github.com/jitsi/docker-jitsi-meet.git
```
2. **Update Jitsi Meet Docker Compose Configuration:**
To enable log collection and analysis, you need to modify the `docker-compose.yml` file for Jitsi Meet components. Add the following configuration to each Jitsi service within the `docker-compose.yml` file:
```yaml
logging:
driver: "json-file"
options:
labels: "service"
```
This configuration ensures that logs are collected in JSON format and tagged with service labels, which is essential for Loki to properly ingest and index the logs.
3. **Start the Docker containers:**
To start all necessary services, including Jitsi Meet components, Grafana, Loki, and OpenTelemetry, run:
```bash
docker-compose -f docker-compose.yml -f log-analyser.yml -f grafana.yml up -d
```
- This command will start the Jitsi Meet components from `docker-compose.yml`, the log analysis tools from `log-analyser.yml`, and Grafana from `grafana.yml`. The logs from Jitsi Meet components will automatically be sent to Grafana through Loki.
- **Note:** To use only Grafana for visualization without log analysis, you can use just `grafana.yml` alone. However, for the complete log analysis project, you need both `log-analyser.yml` and `grafana.yml`.
### Access Grafana
1. **Open your web browser and navigate to [http://localhost:3000](http://localhost:3000).**
2. **Log in to Grafana:**
Use the default credentials:
```
Username: admin
Password: admin
```
3. **Dashboard Setup:**
The dashboards for Jitsi Meet components are pre-configured and will be automatically available in Grafana. You can explore these dashboards to view and analyze logs.
## Usage
- **Log Parsing and Visualization:** After setting up, use Grafana to explore and visualize your logs. Check the pre-configured dashboards and panels to monitor and analyze log data from Jitsi Meet components effectively.
## Acknowledgements
Thank you for exploring this project!
For detailed documentation, follow the [Jitsi Handbook](https://jitsi.github.io/handbook/docs/intro), you can follow the Docker and Log-Analyser guides under Self-Hosting Guide > Deployment guide.
If you have any questions or need further assistance, please feel free to reach out.

View File

@@ -0,0 +1,11 @@
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /etc/grafana/provisioning/dashboards

View File

@@ -0,0 +1,706 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 7,
"x": 0,
"y": 0
},
"id": 4,
"options": {
"minVizHeight": 75,
"minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "container_memory_percent_ratio * 100",
"instant": false,
"legendFormat": "Memory Usage (in %)",
"range": true,
"refId": "A"
}
],
"title": "Memory Usage",
"type": "gauge"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 7,
"x": 7,
"y": 0
},
"id": 2,
"options": {
"minVizHeight": 75,
"minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"exemplar": false,
"expr": "container_cpu_utilization_ratio * 100",
"format": "time_series",
"instant": false,
"legendFormat": "CPU Utilization (in %)",
"range": true,
"refId": "A"
}
],
"title": "CPU Utilization",
"type": "gauge"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 10,
"x": 14,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "sum(rate(container_blockio_io_service_bytes_recursive_total{operation=\"read\"}[5m])) ",
"hide": false,
"instant": false,
"legendFormat": "Read Operation",
"range": true,
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "sum(rate(container_blockio_io_service_bytes_recursive_total{operation=\"write\"}[5m])) ",
"hide": false,
"instant": false,
"legendFormat": "Write Operation",
"range": true,
"refId": "C"
}
],
"title": "Block IO in bytes",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "rate(container_cpu_usage_kernelmode_nanoseconds_total[5m])",
"instant": false,
"legendFormat": "Kernel Mode",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "rate(container_cpu_usage_usermode_nanoseconds_total[5m])",
"hide": false,
"instant": false,
"legendFormat": "User Mode",
"range": true,
"refId": "B"
}
],
"title": "CPU usage in different modes",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 5,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "(container_memory_usage_total_bytes / container_memory_usage_limit_bytes) * 100",
"instant": false,
"legendFormat": "Total Bytes Read/Written",
"range": true,
"refId": "A"
}
],
"title": "Container memory usage vs limit",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"exemplar": false,
"expr": "rate(container_network_io_usage_rx_bytes_total{interface=\"eth0\"}[5m])",
"instant": false,
"legendFormat": "Network bytes received",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "rate(container_network_io_usage_tx_bytes_total{interface=\"eth0\"}[5m])",
"hide": false,
"instant": false,
"legendFormat": "Network bytes Sent",
"range": true,
"refId": "B"
}
],
"title": "Network bytes sent and received",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "rate(container_network_io_usage_rx_dropped_total{interface=\"eth0\"}[5m])",
"instant": false,
"legendFormat": "Network Bytes Dropped in Receiving",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "d301145e-8c4e-4027-bf6e-43e81f095020"
},
"editorMode": "code",
"expr": "rate(container_network_io_usage_tx_dropped_total{interface=\"eth0\"}[5m])",
"hide": false,
"instant": false,
"legendFormat": "Network Bytes dropped in Sending",
"range": true,
"refId": "B"
}
],
"title": "Network Packets dropped",
"type": "timeseries"
}
],
"refresh": "5s",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-24h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Docker Statistics",
"uid": "c67742f2-7db9-489b-90fa-a13f4655806a",
"version": 3,
"weekStart": ""
}

View File

@@ -0,0 +1,460 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 6,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "{exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-jicofo\"",
"queryType": "range",
"refId": "A"
}
],
"title": "Jicofo Logs",
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"displayLabels": [
"percent"
],
"legend": {
"calcs": [],
"displayMode": "hidden",
"placement": "right",
"showLegend": false,
"values": []
},
"pieType": "pie",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "b8130a28-4867-4668-917d-539c93852857"
},
"editorMode": "code",
"expr": "sum by (attributes_level) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-jicofo\"| line_format \"{{.log}}\" | logfmt | pattern \"[<_>] <_level>: <_>\"[5m])\n)",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Jicofo Log Levels Pie Chart",
"type": "piechart"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 1,
"options": {
"displayMode": "lcd",
"minVizHeight": 10,
"minVizWidth": 0,
"namePlacement": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showUnfilled": true,
"valueMode": "color"
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "b8130a28-4867-4668-917d-539c93852857"
},
"editorMode": "code",
"expr": "sum by (attributes_level, attributes_attrs_service) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-jicofo\"| line_format \"{{.attributes_message}}\" | logfmt | pattern \"[<_>] <attributes_level>#<attributes_attrs_service>: <_>\"[5m]))",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Jicofo Log Levels Bar Chart",
"transformations": [],
"type": "bargauge"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 100,
"gradientMode": "hue",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "hidden",
"placement": "right",
"showLegend": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "sum by (attributes_codefile) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-jicofo\"| attributes_level=\"ERROR\" | line_format \"{{.attributes_message}}\" | logfmt | pattern \"[<_>] <attributes_level>#<attributes_attrs_service>: <_>\"[5m]))",
"queryType": "range",
"refId": "A"
}
],
"title": "Jicofo Total Rate of ERROR Logs Aggregated by Code File",
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"description": "This panel shows the number of conference requests over time.",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 100,
"gradientMode": "hue",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "hidden",
"placement": "right",
"showLegend": false
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "count_over_time({exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-jicofo\" |= \"Conference request\" [1m])",
"queryType": "range",
"refId": "A"
}
],
"title": "Jicofo Number of Conference Requests",
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 5,
"options": {
"minVizHeight": 75,
"minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum(count_over_time({exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-jicofo\" |~ \"Member left|Terminating|Removed participant\" [1m]))",
"queryType": "range",
"refId": "A"
}
],
"title": "Jicofo Total Counts of Member Left, Terminating, Removed Participant",
"type": "gauge"
}
],
"refresh": "",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Jicofo Dashboard",
"uid": "f2dcfe84-3c27-4b1d-8583-bc2c97a8d22d",
"version": 20,
"weekStart": ""
}

View File

@@ -0,0 +1,173 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"fillOpacity": 80,
"gradientMode": "opacity",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 1,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 13,
"w": 24,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"barRadius": 0,
"barWidth": 1,
"fullHighlight": false,
"groupWidth": 0.7,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "b8130a28-4867-4668-917d-539c93852857"
},
"editorMode": "code",
"expr": "sum by (attributes_attrs_service) (\n rate({exporter=\"OTLP\"} | json | line_format \"{{.attributes_message}}\" | logfmt | pattern \"[<_>] <_level>: <_>\"[5m]))",
"legendFormat": "{{attributes_attrs_service}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Jicofo, Prosody, Jitsi Web and JVB Log Counts",
"type": "barchart"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 13
},
"id": 2,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "{exporter=\"OTLP\"} ",
"queryType": "range",
"refId": "A"
}
],
"title": "Jitsi All Logs (Jicofo, Prosody, JVB, Web)",
"type": "logs"
}
],
"refresh": "",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Jitsi All Components Dashboard",
"uid": "b75d666d-4537-45e2-94a1-2783f9362b65",
"version": 14,
"weekStart": ""
}

View File

@@ -0,0 +1,275 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 5,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "{exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-web\"",
"queryType": "range",
"refId": "A"
}
],
"title": "Jitsi Web Logs",
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 4,
"options": {
"displayLabels": [
"percent"
],
"legend": {
"calcs": [],
"displayMode": "hidden",
"placement": "right",
"showLegend": false,
"values": []
},
"pieType": "pie",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum by (attributes_level) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-web\"| line_format \"{{.log}}\" | logfmt | pattern \"[<_>] <_level>: <_>\"[5m])\n)",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Jitsi Web Log Levels Pie Chart",
"type": "piechart"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"displayMode": "lcd",
"minVizHeight": 10,
"minVizWidth": 0,
"namePlacement": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showUnfilled": true,
"valueMode": "color"
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum by (attributes_level, attributes_attrs_service) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-web\"| line_format \"{{.attributes_message}}\" | logfmt | pattern \"[<_>] <attributes_level>#<attributes_attrs_service>: <_>\"[5m]))",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Jitsi Web Log Levels Bar Chart",
"type": "bargauge"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "semi-dark-red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 2,
"options": {
"minVizHeight": 75,
"minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum(count_over_time({exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-web\" |= \"GET\" [5m])) by (instance)",
"queryType": "range",
"refId": "A"
}
],
"title": "Jitsi Web Sum of 'GET' Log Counts",
"type": "gauge"
}
],
"refresh": "",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Jitsi Web Dashboard",
"uid": "d1f8ba02-9b8d-42c7-8934-d30ea3559a49",
"version": 4,
"weekStart": ""
}

View File

@@ -0,0 +1,213 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 3,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "{exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-jvb\"",
"queryType": "range",
"refId": "A"
}
],
"title": "JVB Logs",
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"displayLabels": [
"percent",
"name"
],
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"pieType": "pie",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "b8130a28-4867-4668-917d-539c93852857"
},
"editorMode": "code",
"expr": "sum by (attributes_level) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-jvb\"| line_format \"{{.log}}\" | logfmt | pattern \"[<_>] <_level>: <_>\"[5m])\n)",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "JVB Log Levels Pie Chart",
"type": "piechart"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 1,
"options": {
"displayMode": "lcd",
"minVizHeight": 10,
"minVizWidth": 0,
"namePlacement": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showUnfilled": true,
"valueMode": "color"
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "b8130a28-4867-4668-917d-539c93852857"
},
"editorMode": "code",
"expr": "sum by (attributes_level, attributes_attrs_service) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-jvb\" | line_format \"{{.attributes_message}}\" | logfmt | pattern \"[<_>] <attributes_level>#<attributes_attrs_service>: <_>\"[5m]))",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "JVB Log Levels Bar Chart",
"type": "bargauge"
}
],
"refresh": "",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "JVB Dashboard",
"uid": "d53a9efb-ca3b-4f47-af3a-9638de8a35fa",
"version": 10,
"weekStart": ""
}

View File

@@ -0,0 +1,408 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 6,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "{exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-prosody\"",
"queryType": "range",
"refId": "A"
}
],
"title": "Prosody Logs",
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 1,
"options": {
"displayLabels": [
"percent"
],
"legend": {
"calcs": [],
"displayMode": "hidden",
"placement": "right",
"showLegend": false,
"values": []
},
"pieType": "pie",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum by (attributes_level) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-prosody\"| line_format \"{{.log}}\" | logfmt | pattern \"[<_>] <_level>: <_>\"[5m])\n)",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Prosody Log Levels Pie Chart",
"type": "piechart"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 7,
"options": {
"displayMode": "lcd",
"minVizHeight": 10,
"minVizWidth": 0,
"namePlacement": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showUnfilled": true,
"valueMode": "color"
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum by (attributes_level, attributes_attrs_service) (\n rate({exporter=\"OTLP\"} | json|attributes_attrs_service=\"jitsi-prosody\"| line_format \"{{.attributes_message}}\" | logfmt | pattern \"[<_>] <attributes_level>#<attributes_attrs_service>: <_>\"[5m]))",
"legendFormat": "Level: {{attributes_level}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Prosody Log Levels Bar Chart",
"type": "bargauge"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "orange",
"value": 70
},
{
"color": "red",
"value": 85
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 5,
"options": {
"minVizHeight": 75,
"minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum(count_over_time({exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-prosody\" |~ \"Starting room\" [1m]))",
"queryType": "range",
"refId": "A"
}
],
"title": "Prosody Total Number of Rooms Started",
"type": "gauge"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "orange",
"value": 70
},
{
"color": "red",
"value": 85
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 3,
"options": {
"minVizHeight": 75,
"minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum(count_over_time({exporter=\"OTLP\"} | json | attributes_attrs_service=\"jitsi-prosody\" |~ \"Client disconnected\" [1m]))",
"queryType": "range",
"refId": "A"
}
],
"title": "Prosody Total Number of Clients Disconnected",
"type": "gauge"
},
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "orange",
"value": 70
},
{
"color": "red",
"value": 85
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 2,
"options": {
"minVizHeight": 75,
"minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.2.0",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "a4bdfb3e-762a-46e5-a79f-2e7bbe88d444"
},
"editorMode": "code",
"expr": "sum(count_over_time({exporter=\"OTLP\"} | json |attributes_attrs_service=\"jitsi-prosody\" |~ \"Client connected\" [1m]))",
"queryType": "range",
"refId": "A"
}
],
"title": "Prosody Total Number of Clients Connected",
"type": "gauge"
}
],
"refresh": "",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Prosody Loki Dashboard",
"uid": "fe2d57bc-b09b-4688-8037-f642047b0cfc",
"version": 1,
"weekStart": ""
}

View File

@@ -0,0 +1,19 @@
apiVersion: 1
datasources:
- name: Loki
type: loki
uid: a4bdfb3e-762a-46e5-a79f-2e7bbe88d444
access: proxy
url: http://loki:3100
editable: true
apiVersion: 1
- name: Prometheus
type: prometheus
uid: d301145e-8c4e-4027-bf6e-43e81f095020
access: proxy
url: http://prometheus:9090
editable: true
jsonData:
timeInterval: "5s"

View File

@@ -0,0 +1,51 @@
limits_config:
allow_structured_metadata: true
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
instance_addr: 127.0.0.1
path_prefix: /tmp/loki
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
query_range:
results_cache:
cache:
embedded_cache:
enabled: true
max_size_mb: 100
schema_config:
configs:
- from: 2020-10-24
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration
# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/
#
# Statistics help us better understand how Loki is used, and they show us performance
# levels for most users. This helps us prioritize features and documentation.
# For more information on what's sent, look at
# https://github.com/grafana/loki/blob/main/pkg/analytics/stats.go
# Refer to the buildReport method to see what goes into a report.
#
# If you would like to disable reporting, uncomment the following lines:
#analytics:
# reporting_enabled: false

View File

@@ -0,0 +1,88 @@
receivers:
otlp:
protocols:
http:
grpc:
endpoint: 0.0.0.0:4317
filelog/jitsi-containers:
include: ['/var/lib/docker/containers/*/*.log']
encoding: utf-8
operators:
- type: json_parser
id: parser-docker
output: filter_non_tagged_containers
timestamp:
parse_from: attributes.time
layout: '%Y-%m-%dT%H:%M:%S.%LZ'
- type: filter
id: filter_non_tagged_containers
expr: |
(attributes?.attrs?.service != "jitsi-web" and
attributes?.attrs?.service != "jitsi-jicofo" and
attributes?.attrs?.service != "jitsi-jvb" and
attributes?.attrs?.service != "jitsi-prosody")
output: regex_parser_choice
- type: router
id: regex_parser_choice
routes:
- expr: 'attributes.attrs.service == "jitsi-web"'
output: jitsi_web_parser
- expr: 'attributes.attrs.service == "jitsi-jicofo"'
output: jitsi_jicofo_parser
- expr: 'attributes.attrs.service == "jitsi-jvb"'
output: jitsi_jvb_parser
- expr: 'attributes.attrs.service == "jitsi-prosody"'
output: jitsi_prosody_parser
- type: regex_parser
id: jitsi_web_parser
parse_from: attributes.log
regex: "^(?P<message>[\\s\\S]*)$|^(\\[(?P<temp_meta>[\\w\\W]+)\\] (?P<temp_message>[\\S\\s]*)$)"
- type: regex_parser
id: jitsi_jicofo_parser
parse_from: attributes.log
regex: "(^(?P<app>\\w+) (?P<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) (?P<level>\\w+): \\[(?P<pid>\\d+)\\]( \\[(?P<meta>[\\w\\W]+)\\])? (?P<codefile>[\\w\\W]+)(#(?P<codeline>\\d+))?: (?P<message>[\\s\\S]*)$)|^(\\[(?P<temp_meta>[\\w\\W]+)\\] (?P<temp_message>[\\S\\s]*)$)"
output: move_meta_key
- type: regex_parser
id: jitsi_jvb_parser
parse_from: attributes.log
regex: "^(?P<app>JVB) \\[(?P<pid>\\d+)\\] (?P<codefile>[\\w\\.]+)#(?P<codeline>\\d+): (?P<message>[\\S\\s]*)$"
- type: regex_parser
id: jitsi_prosody_parser
parse_from: attributes.log
regex: (^(?<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s+(?<service>\S+)\s+(?<level>\w{0,10})(\t)(?P<message>[\s\S]*)$)|^(\[(?P<temp_meta>[\w\W]+)\] (?P<temp_message>[\S\s]*)$)
output: move_meta_key
- type: move
id: move_meta_key
if: "attributes.temp_meta != nil and attributes.temp_meta != ''"
from: attributes.temp_meta
to: attributes.meta
output: move_message_key
- type: move
id: move_message_key
if: "attributes.temp_message != nil and attributes.temp_message != ''"
from: attributes.temp_message
to: attributes.message
docker_stats:
endpoint: "unix:///var/run/docker.sock"
processors:
batch:
exporters:
debug:
verbosity: detailed
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
prometheus:
endpoint: "0.0.0.0:9464"
service:
pipelines:
logs:
receivers: [otlp, filelog/jitsi-containers]
processors: [batch]
exporters: [loki]
metrics:
receivers: [docker_stats]
processors: [batch]
exporters: [prometheus]

View File

@@ -0,0 +1,13 @@
services:
prometheus:
image: prom/prometheus
container_name: prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
ports:
- 9090:9090
restart: ${RESTART_POLICY:-unless-stopped}
volumes:
- ./prometheus:/etc/prometheus
networks:
meet.jitsi:

View File

@@ -0,0 +1,73 @@
# Prometheus Scraping & Grafana Dashboard for Jitsi
## Overview
This project aims to integrate **Prometheus** and **Grafana** with Jitsi to monitor and visualize performance metrics.
## Features
- **Prometheus Integration**: Collects metrics from Jitsi containers.
- **Grafana Dashboards**: Visualizes the metrics for easy analysis.
## Installation
### Prerequisites
- Docker
- Docker Compose
### Steps
1. **Setup Jitsi with Docker Compose**
Follow the [Jitsi Docker](https://github.com/jitsi/docker-jitsi-meet) setup instructions. <br>
Also, you could follow Self - Hosting guide of Jitsi Meet: [Jitsi handbook](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker/)
2. **Configure Prometheus**
Edit `/prometheus/prometheus.yml` with any **Port / Container name** changes are there to scrape metrics from Jitsi containers:
```yaml
scrape_configs:
- job_name: "jitsi"
static_configs:
- targets: ["prosody:5280", "jvb:8080", "jicofo:8888", "otel:9464"]
```
3. **Run Docker Compose**
The following command turns up the Jitsi Meet:
```bash
docker-compose up -d
```
If you want to add the Prometheus and Grafana for monitoring purpose. Use the following command:
```bash
docker-compose -f docker-compose.yml -f prometheus.yml -f grafana.yml up -d
```
To monitor Docker Engine we need to enable **Open Telemetry** service, which can be turned up from `log-analyser.yml`. Use the following command:
```bash
docker-compose -f docker-compose.yml -f prometheus.yml -f grafana.yml -f log-analyser.yml up -d
```
## Usage
1. **View the Prometheus Targets**
Open [http://localhost:9090](http://localhost:9090) in your browser.
2. **Access Grafana Dashboard**
Open [http://localhost:3000](http://localhost:3000) in your browser.
3. **Import Dashboard**
Import the provided JSON file in Grafana to visualize Jitsi metrics.
## Contributer
[@24kushang](https://github.com/24kushang).

View File

@@ -0,0 +1,5 @@
scrape_configs:
- job_name: "prometheus"
scrape_interval: 5s
static_configs:
- targets: ["prosody:5280","jvb:8080","jicofo:8888","otel:9464"]

View File

@@ -0,0 +1,77 @@
ARG JITSI_REPO=jitsi
ARG BASE_TAG=latest
FROM ${JITSI_REPO}/base:${BASE_TAG} AS builder
RUN apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y \
build-essential \
lua5.4 \
liblua5.4-dev \
libreadline-dev \
git \
unzip \
wget && \
mkdir /tmp/luarocks && \
wget -qO - https://luarocks.github.io/luarocks/releases/luarocks-3.8.0.tar.gz | tar xfz - --strip-components 1 -C /tmp/luarocks && \
cd /tmp/luarocks && ./configure && make && make install && cd - && \
luarocks install basexx 0.4.1-1 && \
luarocks install lua-cjson 2.1.0-1 && \
luarocks install net-url 0.9-1
FROM ${JITSI_REPO}/base:${BASE_TAG}
LABEL org.opencontainers.image.title="Prosody IM"
LABEL org.opencontainers.image.description="XMPP server used for signalling."
LABEL org.opencontainers.image.url="https://prosody.im/"
LABEL org.opencontainers.image.source="https://github.com/jitsi/docker-jitsi-meet"
LABEL org.opencontainers.image.documentation="https://jitsi.github.io/handbook/"
ARG VERSION_JITSI_CONTRIB_PROSODY_PLUGINS="20250923"
ARG VERSION_MATRIX_USER_VERIFICATION_SERVICE_PLUGIN="1.8.0"
ARG PROSODY_PACKAGE="prosody"
RUN set -x && \
wget -qO /etc/apt/trusted.gpg.d/prosody.gpg https://prosody.im/files/prosody-debian-packages.key && \
echo "deb http://packages.prosody.im/debian bookworm main" > /etc/apt/sources.list.d/prosody.list && \
apt-dpkg-wrap apt-get update && \
apt-dpkg-wrap apt-get install -y \
lua5.4 \
$PROSODY_PACKAGE \
libldap-common \
sasl2-bin \
libsasl2-modules-ldap \
lua-cyrussasl \
lua-inspect \
lua-ldap \
lua-luaossl \
lua-sec \
lua-unbound && \
apt-dpkg-wrap apt-get -d install -y jitsi-meet-prosody && \
dpkg -x /var/cache/apt/archives/jitsi-meet-prosody*.deb /tmp/pkg && \
mv /tmp/pkg/usr/share/jitsi-meet/prosody-plugins /prosody-plugins && \
rm -rf /tmp/pkg /var/cache/apt && \
apt-cleanup && \
rm -rf /etc/prosody && \
mv /usr/share/lua/5.3/inspect.lua /usr/share/lua/5.4/ && \
rm -rf /usr/lib/lua/{5.1,5.2,5.3} && \
rm -rf /usr/share/lua/{5.1,5.2,5.3} && \
wget https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification/archive/refs/tags/v$VERSION_MATRIX_USER_VERIFICATION_SERVICE_PLUGIN.tar.gz && \
tar -xf v$VERSION_MATRIX_USER_VERIFICATION_SERVICE_PLUGIN.tar.gz && \
mv prosody-mod-auth-matrix-user-verification-$VERSION_MATRIX_USER_VERIFICATION_SERVICE_PLUGIN/mod_auth_matrix_user_verification.lua /prosody-plugins && \
mv prosody-mod-auth-matrix-user-verification-$VERSION_MATRIX_USER_VERIFICATION_SERVICE_PLUGIN/mod_matrix_power_sync.lua /prosody-plugins && \
rm -rf prosody-mod-auth-matrix-user-verification-$VERSION_MATRIX_USER_VERIFICATION_SERVICE_PLUGIN v$VERSION_MATRIX_USER_VERIFICATION_SERVICE_PLUGIN.tar.gz && \
wget -q https://github.com/jitsi-contrib/prosody-plugins/archive/refs/tags/v$VERSION_JITSI_CONTRIB_PROSODY_PLUGINS.tar.gz && \
tar -xf v$VERSION_JITSI_CONTRIB_PROSODY_PLUGINS.tar.gz && \
mkdir /prosody-plugins-contrib && \
cp -a prosody-plugins-$VERSION_JITSI_CONTRIB_PROSODY_PLUGINS/* /prosody-plugins-contrib && \
rm -rf prosody-plugins-$VERSION_JITSI_CONTRIB_PROSODY_PLUGINS v$VERSION_JITSI_CONTRIB_PROSODY_PLUGINS.tar.gz
COPY rootfs/ /
COPY --from=builder /usr/local/lib/lua/5.4 /usr/local/lib/lua/5.4
COPY --from=builder /usr/local/share/lua/5.4 /usr/local/share/lua/5.4
EXPOSE 5222 5280
VOLUME ["/config", "/prosody-plugins-custom"]

View File

@@ -0,0 +1,36 @@
{{ $REGION_NAME := .Env.PROSODY_REGION_NAME | default "default" -}}
{{ $RELEASE_NUMBER := .Env.RELEASE_NUMBER | default "" -}}
{{ $SHARD_NAME := .Env.SHARD | default "default" -}}
{{ $JVB_XMPP_AUTH_DOMAIN := .Env.JVB_XMPP_AUTH_DOMAIN | default "auth.jvb.meet.jitsi" -}}
{{ $JVB_XMPP_INTERNAL_MUC_DOMAIN := .Env.JVB_XMPP_INTERNAL_MUC_DOMAIN | default "muc.jvb.meet.jitsi" -}}
{{ $JVB_AUTH_USER := .Env.JVB_AUTH_USER | default "jvb" -}}
admins = {
"focus@{{ $JVB_XMPP_AUTH_DOMAIN }}",
"{{ $JVB_AUTH_USER }}@{{ $JVB_XMPP_AUTH_DOMAIN }}"
}
plugin_paths = { "/prosody-plugins/", "/prosody-plugins-custom", "/prosody-plugins-contrib" }
VirtualHost "{{ $JVB_XMPP_AUTH_DOMAIN }}"
modules_enabled = {
"smacks";
}
authentication = "internal_hashed"
ssl = {
key = "/config/certs/{{ $JVB_XMPP_AUTH_DOMAIN }}.key";
certificate = "/config/certs/{{ $JVB_XMPP_AUTH_DOMAIN }}.crt";
}
smacks_hibernation_time = 15;
Component "{{ $JVB_XMPP_INTERNAL_MUC_DOMAIN }}" "muc"
modules_enabled = {
"muc_hide_all";
"muc_filter_access";
}
storage = "memory"
muc_room_cache_size = 10000
muc_filter_whitelist="{{ $JVB_XMPP_AUTH_DOMAIN }}"
muc_room_locking = false
muc_room_default_public_jids = true

View File

@@ -0,0 +1,470 @@
{{ $AUTH_TYPE := .Env.AUTH_TYPE | default "internal" -}}
{{ $C2S_REQUIRE_ENCRYPTION := .Env.PROSODY_C2S_REQUIRE_ENCRYPTION | default "1" | toBool -}}
{{ $DISABLE_POLLS := .Env.DISABLE_POLLS | default "false" | toBool -}}
{{ $ENABLE_APP_SECRET := .Env.JWT_APP_SECRET | default "false" | toBool -}}
{{ $ENABLE_AUTH := .Env.ENABLE_AUTH | default "0" | toBool -}}
{{ $ENABLE_AV_MODERATION := .Env.ENABLE_AV_MODERATION | default "true" | toBool -}}
{{ $ENABLE_BREAKOUT_ROOMS := .Env.ENABLE_BREAKOUT_ROOMS | default "true" | toBool -}}
{{ $ENABLE_END_CONFERENCE := .Env.ENABLE_END_CONFERENCE | default "true" | toBool -}}
{{ $ENABLE_FILTER_MESSAGES := .Env.PROSODY_ENABLE_FILTER_MESSAGES | default "false" | toBool -}}
{{ $ENABLE_GUEST_DOMAIN := and $ENABLE_AUTH (.Env.ENABLE_GUESTS | default "0" | toBool) -}}
{{ $ENABLE_JAAS_COMPONENTS := .Env.ENABLE_JAAS_COMPONENTS | default "0" | toBool -}}
{{ $ENABLE_LOBBY := .Env.ENABLE_LOBBY | default "true" | toBool -}}
{{ $ENABLE_RATE_LIMITS := .Env.PROSODY_ENABLE_RATE_LIMITS | default "0" | toBool -}}
{{ $ENABLE_RECORDING := .Env.ENABLE_RECORDING | default "0" | toBool -}}
{{ $ENABLE_RECORDING_METADATA := .Env.PROSODY_ENABLE_RECORDING_METADATA | default "1" | toBool -}}
{{ $ENABLE_SUBDOMAINS := .Env.ENABLE_SUBDOMAINS | default "true" | toBool -}}
{{ $ENABLE_TRANSCRIPTIONS := .Env.ENABLE_TRANSCRIPTIONS | default "0" | toBool -}}
{{ $ENABLE_VISITORS := .Env.ENABLE_VISITORS | default "0" | toBool -}}
{{ $ENABLE_XMPP_WEBSOCKET := .Env.ENABLE_XMPP_WEBSOCKET | default "1" | toBool -}}
{{ $ENV := .Env -}}
{{ $GUEST_AUTH_TYPE := .Env.PROSODY_GUEST_AUTH_TYPE | default "jitsi-anonymous" -}}
{{ $JIBRI_RECORDER_USER := .Env.JIBRI_RECORDER_USER | default "recorder" -}}
{{ $JIBRI_XMPP_USER := .Env.JIBRI_XMPP_USER | default "jibri" -}}
{{ $JIGASI_TRANSCRIBER_USER := .Env.JIGASI_TRANSCRIBER_USER | default "transcriber" -}}
{{ $JIGASI_XMPP_USER := .Env.JIGASI_XMPP_USER | default "jigasi" -}}
{{ $JVB_AUTH_USER := .Env.JVB_AUTH_USER | default "jvb" -}}
{{ $JWT_ALLOW_EMPTY := .Env.JWT_ALLOW_EMPTY | default "0" | toBool -}}
{{ $JWT_ASAP_KEYSERVER := .Env.JWT_ASAP_KEYSERVER | default "" -}}
{{ $JWT_AUTH_TYPE := .Env.JWT_AUTH_TYPE | default "token" -}}
{{ $JWT_ENABLE_DOMAIN_VERIFICATION := .Env.JWT_ENABLE_DOMAIN_VERIFICATION | default "false" | toBool -}}
{{ $JWT_TOKEN_AUTH_MODULE := .Env.JWT_TOKEN_AUTH_MODULE | default "token_verification" -}}
{{ $MATRIX_LOBBY_BYPASS := .Env.MATRIX_LOBBY_BYPASS | default "0" | toBool -}}
{{ $MATRIX_UVS_ISSUER := .Env.MATRIX_UVS_ISSUER | default "issuer" -}}
{{ $MATRIX_UVS_SYNC_POWER_LEVELS := .Env.MATRIX_UVS_SYNC_POWER_LEVELS | default "0" | toBool -}}
{{ $PROSODY_AUTH_TYPE := .Env.PROSODY_AUTH_TYPE | default $AUTH_TYPE -}}
{{ $PROSODY_RESERVATION_ENABLED := .Env.PROSODY_RESERVATION_ENABLED | default "false" | toBool -}}
{{ $PROSODY_RESERVATION_REST_BASE_URL := .Env.PROSODY_RESERVATION_REST_BASE_URL | default "" -}}
{{ $PUBLIC_URL := .Env.PUBLIC_URL | default "https://localhost:8443" -}}
{{ $PUBLIC_URL_DOMAIN := $PUBLIC_URL | trimPrefix "https://" | trimSuffix "/" -}}
{{ $RATE_LIMIT_ALLOW_RANGES := .Env.PROSODY_RATE_LIMIT_ALLOW_RANGES | default "10.0.0.0/8" -}}
{{ $RATE_LIMIT_CACHE_SIZE := .Env.PROSODY_RATE_LIMIT_CACHE_SIZE | default "10000" -}}
{{ $RATE_LIMIT_LOGIN_RATE := .Env.PROSODY_RATE_LIMIT_LOGIN_RATE | default "3" -}}
{{ $RATE_LIMIT_SESSION_RATE := .Env.PROSODY_RATE_LIMIT_SESSION_RATE | default "200" -}}
{{ $RATE_LIMIT_TIMEOUT := .Env.PROSODY_RATE_LIMIT_TIMEOUT | default "60" -}}
{{ $XMPP_AUTH_DOMAIN := .Env.XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $XMPP_DOMAIN := .Env.XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $XMPP_GUEST_DOMAIN := .Env.XMPP_GUEST_DOMAIN | default "guest.meet.jitsi" -}}
{{ $XMPP_INTERNAL_MUC_DOMAIN := .Env.XMPP_INTERNAL_MUC_DOMAIN | default "internal-muc.meet.jitsi" -}}
{{ $XMPP_MUC_DOMAIN := .Env.XMPP_MUC_DOMAIN | default "muc.meet.jitsi" -}}
{{ $XMPP_MUC_DOMAIN_PREFIX := (split "." $XMPP_MUC_DOMAIN)._0 -}}
{{ $XMPP_HIDDEN_DOMAIN := .Env.XMPP_HIDDEN_DOMAIN | default "hidden.meet.jitsi" -}}
admins = {
{{ if .Env.JIGASI_XMPP_PASSWORD }}
"{{ $JIGASI_XMPP_USER }}@{{ $XMPP_AUTH_DOMAIN }}",
{{ end }}
{{ if .Env.JIBRI_XMPP_PASSWORD }}
"{{ $JIBRI_XMPP_USER }}@{{ $XMPP_AUTH_DOMAIN }}",
{{ end }}
"focus@{{ $XMPP_AUTH_DOMAIN }}",
"{{ $JVB_AUTH_USER }}@{{ $XMPP_AUTH_DOMAIN }}"
}
unlimited_jids = {
"focus@{{ $XMPP_AUTH_DOMAIN }}",
"{{ $JVB_AUTH_USER }}@{{ $XMPP_AUTH_DOMAIN }}"
}
plugin_paths = { "/prosody-plugins/", "/prosody-plugins-custom", "/prosody-plugins-contrib" }
muc_mapper_domain_base = "{{ $XMPP_DOMAIN }}";
muc_mapper_domain_prefix = "{{ $XMPP_MUC_DOMAIN_PREFIX }}";
recorder_prefixes = { "{{ $JIBRI_RECORDER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}" };
http_default_host = "{{ $XMPP_DOMAIN }}"
{{ if and $ENABLE_AUTH (or (eq $PROSODY_AUTH_TYPE "jwt") (eq $PROSODY_AUTH_TYPE "hybrid_matrix_token")) .Env.JWT_ACCEPTED_ISSUERS }}
asap_accepted_issuers = { "{{ join "\",\"" (splitList "," .Env.JWT_ACCEPTED_ISSUERS | compact) }}" }
{{ end }}
{{ if and $ENABLE_AUTH (or (eq $PROSODY_AUTH_TYPE "jwt") (eq $PROSODY_AUTH_TYPE "hybrid_matrix_token")) .Env.JWT_ACCEPTED_AUDIENCES }}
asap_accepted_audiences = { "{{ join "\",\"" (splitList "," .Env.JWT_ACCEPTED_AUDIENCES | compact) }}" }
{{ end }}
{{ if and $ENABLE_AUTH (or (eq $PROSODY_AUTH_TYPE "jwt") (eq $PROSODY_AUTH_TYPE "hybrid_matrix_token")) .Env.JWT_ACCEPTED_ALLOWNER_ISSUERS }}
allowner_issuers = { "{{ join "\",\"" (splitList "," .Env.JWT_ACCEPTED_ALLOWNER_ISSUERS | compact) }}" }
{{ end }}
consider_bosh_secure = true;
consider_websocket_secure = true;
{{ if $ENABLE_XMPP_WEBSOCKET }}
smacks_max_unacked_stanzas = 5;
smacks_hibernation_time = 60;
smacks_max_old_sessions = 1;
{{ end }}
{{ if $ENABLE_JAAS_COMPONENTS }}
VirtualHost "jigasi.meet.jitsi"
modules_enabled = {
"bosh";
"muc_password_check";
}
authentication = "token"
app_id = "jitsi";
asap_key_server = "https://jaas-public-keys.jitsi.net/jitsi-components/prod-8x8"
asap_accepted_issuers = { "jaas-components" }
asap_accepted_audiences = { "jigasi.{{ $PUBLIC_URL_DOMAIN }}" }
{{ end }}
VirtualHost "{{ $XMPP_DOMAIN }}"
{{ if $ENABLE_AUTH }}
{{ if eq $PROSODY_AUTH_TYPE "jwt" }}
{{ if .Env.JWT_SIGN_TYPE }}
signature_algorithm = "{{ .Env.JWT_SIGN_TYPE }}"
{{ end -}}
authentication = "{{ $JWT_AUTH_TYPE }}"
app_id = "{{ .Env.JWT_APP_ID }}"
{{ if $ENABLE_APP_SECRET }}
app_secret = "{{ .Env.JWT_APP_SECRET }}"
{{ end }}
allow_empty_token = {{ $JWT_ALLOW_EMPTY }}
{{ if $JWT_ASAP_KEYSERVER }}
asap_key_server = "{{ .Env.JWT_ASAP_KEYSERVER }}"
{{ end }}
enable_domain_verification = {{ $JWT_ENABLE_DOMAIN_VERIFICATION }}
{{ else if eq $PROSODY_AUTH_TYPE "ldap" }}
authentication = "cyrus"
cyrus_application_name = "xmpp"
allow_unencrypted_plain_auth = true
{{ else if eq $PROSODY_AUTH_TYPE "matrix" }}
authentication = "matrix_user_verification"
app_id = "{{ $MATRIX_UVS_ISSUER }}"
uvs_base_url = "{{ .Env.MATRIX_UVS_URL }}"
{{ if .Env.MATRIX_UVS_AUTH_TOKEN }}
uvs_auth_token = "{{ .Env.MATRIX_UVS_AUTH_TOKEN }}"
{{ end }}
{{ if $MATRIX_UVS_SYNC_POWER_LEVELS }}
uvs_sync_power_levels = true
{{ end }}
{{ else if eq $PROSODY_AUTH_TYPE "hybrid_matrix_token" }}
authentication = "hybrid_matrix_token"
app_id = "{{ .Env.JWT_APP_ID }}"
{{ if $ENABLE_APP_SECRET }}
app_secret = "{{ .Env.JWT_APP_SECRET }}"
{{ end }}
allow_empty_token = {{ $JWT_ALLOW_EMPTY }}
enable_domain_verification = {{ $JWT_ENABLE_DOMAIN_VERIFICATION }}
uvs_base_url = "{{ .Env.MATRIX_UVS_URL }}"
{{ if .Env.MATRIX_UVS_ISSUER }}
uvs_issuer = "{{ .Env.MATRIX_UVS_ISSUER }}"
{{ end }}
{{ if .Env.MATRIX_UVS_AUTH_TOKEN }}
uvs_auth_token = "{{ .Env.MATRIX_UVS_AUTH_TOKEN }}"
{{ end }}
{{ else if eq $PROSODY_AUTH_TYPE "internal" }}
authentication = "internal_hashed"
disable_sasl_mechanisms={ "DIGEST-MD5", "OAUTHBEARER" }
{{ end }}
{{ else }}
authentication = "jitsi-anonymous"
{{ end }}
ssl = {
key = "/config/certs/{{ $XMPP_DOMAIN }}.key";
certificate = "/config/certs/{{ $XMPP_DOMAIN }}.crt";
}
modules_enabled = {
"bosh";
"features_identity";
{{ if $ENABLE_XMPP_WEBSOCKET }}
"websocket";
"smacks"; -- XEP-0198: Stream Management
{{ end }}
"conference_duration";
{{ if $ENABLE_LOBBY }}
"muc_lobby_rooms";
{{ end }}
{{ if $ENABLE_BREAKOUT_ROOMS }}
"muc_breakout_rooms";
{{ end }}
{{ if .Env.XMPP_MODULES }}
"{{ join "\";\n \"" (splitList "," .Env.XMPP_MODULES | compact) }}";
{{ end }}
{{ if and $ENABLE_AUTH (eq $PROSODY_AUTH_TYPE "ldap") }}
"auth_cyrus";
{{end}}
{{ if $PROSODY_RESERVATION_ENABLED }}
"reservations";
{{ end }}
{{ if $ENABLE_VISITORS }}
"visitors";
{{ end }}
{{- if and $ENABLE_RECORDING_METADATA $ENABLE_AUTH (eq $PROSODY_AUTH_TYPE "jwt") $ENABLE_RECORDING }}
"jibri_session";
{{- end }}
}
main_muc = "{{ $XMPP_MUC_DOMAIN }}"
{{ if $ENABLE_LOBBY }}
lobby_muc = "lobby.{{ $XMPP_DOMAIN }}"
{{ if or $ENABLE_RECORDING $ENABLE_TRANSCRIPTIONS }}
muc_lobby_whitelist = { "{{ $XMPP_HIDDEN_DOMAIN }}" }
{{ end }}
{{ end }}
{{ if $PROSODY_RESERVATION_ENABLED }}
reservations_api_prefix = "{{ $PROSODY_RESERVATION_REST_BASE_URL }}"
{{ end }}
{{ if $ENABLE_BREAKOUT_ROOMS }}
breakout_rooms_muc = "breakout.{{ $XMPP_DOMAIN }}"
{{ end }}
c2s_require_encryption = {{ $C2S_REQUIRE_ENCRYPTION }}
{{ if $ENABLE_VISITORS -}}
visitors_ignore_list = { "{{ $XMPP_HIDDEN_DOMAIN }}" }
{{ end }}
{{ if .Env.XMPP_CONFIGURATION -}}
{{ join "\n " (splitList "," .Env.XMPP_CONFIGURATION | compact) }}
{{ end -}}
{{ if $ENABLE_GUEST_DOMAIN }}
VirtualHost "{{ $XMPP_GUEST_DOMAIN }}"
authentication = "{{ $GUEST_AUTH_TYPE }}"
modules_enabled = {
{{ if $ENABLE_XMPP_WEBSOCKET }}
"smacks"; -- XEP-0198: Stream Management
{{ end }}
{{ if .Env.XMPP_MODULES }}
"{{ join "\";\n \"" (splitList "," .Env.XMPP_MODULES | compact) }}";
{{ end }}
}
main_muc = "{{ $XMPP_MUC_DOMAIN }}"
c2s_require_encryption = {{ $C2S_REQUIRE_ENCRYPTION }}
{{ if $ENABLE_VISITORS }}
allow_anonymous_s2s = true
{{ end }}
{{ if $ENABLE_LOBBY }}
lobby_muc = "lobby.{{ $XMPP_DOMAIN }}"
{{ end }}
{{ if $ENABLE_BREAKOUT_ROOMS }}
breakout_rooms_muc = "breakout.{{ $XMPP_DOMAIN }}"
{{ end }}
{{ if .Env.XMPP_CONFIGURATION -}}
{{ join "\n " (splitList "," .Env.XMPP_CONFIGURATION | compact) }}
{{ end -}}
{{ end }}
VirtualHost "{{ $XMPP_AUTH_DOMAIN }}"
ssl = {
key = "/config/certs/{{ $XMPP_AUTH_DOMAIN }}.key";
certificate = "/config/certs/{{ $XMPP_AUTH_DOMAIN }}.crt";
}
modules_enabled = {
"limits_exception";
{{- if and $ENABLE_RECORDING_METADATA $ENABLE_AUTH (eq $PROSODY_AUTH_TYPE "jwt") $ENABLE_RECORDING }}
"jibri_session";
{{- end }}
"smacks";
}
authentication = "internal_hashed"
smacks_hibernation_time = 15;
{{ if or $ENABLE_RECORDING $ENABLE_TRANSCRIPTIONS }}
VirtualHost "{{ $XMPP_HIDDEN_DOMAIN }}"
modules_enabled = {
"smacks";
}
authentication = "internal_hashed"
{{ end }}
Component "{{ $XMPP_INTERNAL_MUC_DOMAIN }}" "muc"
storage = "memory"
modules_enabled = {
"muc_hide_all";
"muc_filter_access";
{{ if .Env.XMPP_INTERNAL_MUC_MODULES -}}
"{{ join "\";\n\"" (splitList "," .Env.XMPP_INTERNAL_MUC_MODULES | compact) }}";
{{ end -}}
}
restrict_room_creation = true
muc_filter_whitelist="{{ $XMPP_AUTH_DOMAIN }}"
muc_room_locking = false
muc_room_default_public_jids = true
muc_room_cache_size = 1000
muc_tombstones = false
muc_room_allow_persistent = false
Component "{{ $XMPP_MUC_DOMAIN }}" "muc"
restrict_room_creation = true
storage = "memory"
modules_enabled = {
"muc_hide_all";
"muc_meeting_id";
{{ if .Env.XMPP_MUC_MODULES -}}
"{{ join "\";\n \"" (splitList "," .Env.XMPP_MUC_MODULES | compact) }}";
{{ end -}}
{{ if and $ENABLE_AUTH (or (eq $PROSODY_AUTH_TYPE "jwt") (eq $PROSODY_AUTH_TYPE "hybrid_matrix_token")) -}}
"{{ $JWT_TOKEN_AUTH_MODULE }}";
{{ end }}
{{ if and $ENABLE_AUTH (eq $PROSODY_AUTH_TYPE "matrix") $MATRIX_UVS_SYNC_POWER_LEVELS -}}
"matrix_power_sync";
{{ end -}}
{{ if and $ENABLE_AUTH (eq $PROSODY_AUTH_TYPE "hybrid_matrix_token") $MATRIX_UVS_SYNC_POWER_LEVELS -}}
"matrix_affiliation";
{{ end -}}
{{ if and $ENABLE_AUTH (eq $PROSODY_AUTH_TYPE "hybrid_matrix_token") $MATRIX_LOBBY_BYPASS -}}
"matrix_lobby_bypass";
{{ end -}}
{{ if $ENABLE_SUBDOMAINS -}}
"muc_domain_mapper";
{{ end -}}
{{ if $ENABLE_RATE_LIMITS -}}
"muc_rate_limit";
"rate_limit";
{{ end -}}
{{ if .Env.MAX_PARTICIPANTS }}
"muc_max_occupants";
{{ end }}
"muc_password_whitelist";
{{ if $ENABLE_FILTER_MESSAGES }}
"filter_messages";
{{ end }}
}
{{ if $ENABLE_RATE_LIMITS -}}
-- Max allowed join/login rate in events per second.
rate_limit_login_rate = {{ $RATE_LIMIT_LOGIN_RATE }};
-- The rate to which sessions from IPs exceeding the join rate will be limited, in bytes per second.
rate_limit_session_rate = {{ $RATE_LIMIT_SESSION_RATE }};
-- The time in seconds, after which the limit for an IP address is lifted.
rate_limit_timeout = {{ $RATE_LIMIT_TIMEOUT }};
-- List of regular expressions for IP addresses that are not limited by this module.
rate_limit_whitelist = {
"127.0.0.1";
{{ range $index, $cidr := (splitList "," $RATE_LIMIT_ALLOW_RANGES | compact) }}
"{{ $cidr }}";
{{ end }}
};
rate_limit_whitelist_hosts = {
"{{ $XMPP_HIDDEN_DOMAIN }}";
}
{{ end -}}
-- The size of the cache that saves state for IP addresses
rate_limit_cache_size = {{ $RATE_LIMIT_CACHE_SIZE }};
muc_room_cache_size = 10000
muc_room_locking = false
muc_room_default_public_jids = true
{{ if .Env.XMPP_MUC_CONFIGURATION -}}
{{ join "\n " (splitList "," .Env.XMPP_MUC_CONFIGURATION | compact) }}
{{ end -}}
{{ if .Env.MAX_PARTICIPANTS }}
muc_access_whitelist = {
"focus@{{ $XMPP_AUTH_DOMAIN }}";
{{- if $ENABLE_RECORDING }}
"{{ $JIBRI_RECORDER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}";
{{- end }}
{{- if $ENABLE_TRANSCRIPTIONS }}
"{{ $JIGASI_TRANSCRIBER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}";
{{- end }}
}
muc_max_occupants = "{{ .Env.MAX_PARTICIPANTS }}"
{{ end }}
muc_password_whitelist = {
"focus@{{ $XMPP_AUTH_DOMAIN }}";
{{- if $ENABLE_RECORDING }}
"{{ $JIBRI_RECORDER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}";
{{- end }}
{{- if $ENABLE_TRANSCRIPTIONS }}
"{{ $JIGASI_TRANSCRIBER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}";
{{- end }}
}
muc_tombstones = false
muc_room_allow_persistent = false
Component "focus.{{ $XMPP_DOMAIN }}" "client_proxy"
target_address = "focus@{{ $XMPP_AUTH_DOMAIN }}"
Component "speakerstats.{{ $XMPP_DOMAIN }}" "speakerstats_component"
muc_component = "{{ $XMPP_MUC_DOMAIN }}"
{{- if .Env.XMPP_SPEAKERSTATS_MODULES }}
modules_enabled = {
"{{ join "\";\n \"" (splitList "," .Env.XMPP_SPEAKERSTATS_MODULES | compact) }}";
}
{{- end }}
{{ if $ENABLE_END_CONFERENCE }}
Component "endconference.{{ $XMPP_DOMAIN }}" "end_conference"
muc_component = "{{ $XMPP_MUC_DOMAIN }}"
{{ end }}
{{ if $ENABLE_AV_MODERATION }}
Component "avmoderation.{{ $XMPP_DOMAIN }}" "av_moderation_component"
muc_component = "{{ $XMPP_MUC_DOMAIN }}"
{{ end }}
{{ if $ENABLE_LOBBY }}
Component "lobby.{{ $XMPP_DOMAIN }}" "muc"
storage = "memory"
restrict_room_creation = true
muc_tombstones = false
muc_room_allow_persistent = false
muc_room_cache_size = 10000
muc_room_locking = false
muc_room_default_public_jids = true
{{- if .Env.MAX_PARTICIPANTS }}
muc_max_occupants = "{{ .Env.MAX_PARTICIPANTS }}"
{{- end }}
modules_enabled = {
"muc_hide_all";
{{- if $ENABLE_RATE_LIMITS }}
"muc_rate_limit";
{{- end }}
{{- if .Env.MAX_PARTICIPANTS }}
"muc_max_occupants";
{{- end }}
{{- if .Env.XMPP_LOBBY_MUC_MODULES }}
"{{ join "\";\n \"" (splitList "," .Env.XMPP_LOBBY_MUC_MODULES | compact) }}";
{{- end }}
}
{{ end }}
{{ if $ENABLE_BREAKOUT_ROOMS }}
Component "breakout.{{ $XMPP_DOMAIN }}" "muc"
storage = "memory"
restrict_room_creation = true
muc_room_cache_size = 10000
muc_room_locking = false
muc_room_default_public_jids = true
muc_tombstones = false
muc_room_allow_persistent = false
modules_enabled = {
"muc_hide_all";
"muc_meeting_id";
{{ if $ENABLE_RATE_LIMITS -}}
"muc_rate_limit";
{{ end -}}
{{ if .Env.XMPP_BREAKOUT_MUC_MODULES -}}
"{{ join "\";\n \"" (splitList "," .Env.XMPP_BREAKOUT_MUC_MODULES | compact) }}";
{{ end -}}
}
{{ end }}
Component "metadata.{{ $XMPP_DOMAIN }}" "room_metadata_component"
muc_component = "{{ $XMPP_MUC_DOMAIN }}"
breakout_rooms_component = "breakout.{{ $XMPP_DOMAIN }}"
{{ if $ENABLE_VISITORS }}
Component "visitors.{{ $XMPP_DOMAIN }}" "visitors_component"
auto_allow_visitor_promotion = true
always_visitors_enabled = true
{{ end }}
{{ if not $DISABLE_POLLS -}}
Component "polls.{{ $XMPP_DOMAIN }}" "polls_component"
{{ end -}}

View File

@@ -0,0 +1,197 @@
{{ $DISABLE_POLLS := .Env.DISABLE_POLLS | default "false" | toBool -}}
{{ $ENABLE_AUTH := .Env.ENABLE_AUTH | default "0" | toBool -}}
{{ $ENABLE_GUEST_DOMAIN := and $ENABLE_AUTH (.Env.ENABLE_GUESTS | default "0" | toBool) -}}
{{ $ENABLE_RATE_LIMITS := .Env.PROSODY_ENABLE_RATE_LIMITS | default "0" | toBool -}}
{{ $ENABLE_RECORDING := .Env.ENABLE_RECORDING | default "0" | toBool -}}
{{ $ENABLE_SUBDOMAINS := .Env.ENABLE_SUBDOMAINS | default "true" | toBool -}}
{{ $ENABLE_TRANSCRIPTIONS := .Env.ENABLE_TRANSCRIPTIONS | default "0" | toBool -}}
{{ $ENABLE_XMPP_WEBSOCKET := .Env.ENABLE_XMPP_WEBSOCKET | default "1" | toBool -}}
{{ $JIBRI_RECORDER_USER := .Env.JIBRI_RECORDER_USER | default "recorder" -}}
{{ $JIGASI_TRANSCRIBER_USER := .Env.JIGASI_TRANSCRIBER_USER | default "transcriber" -}}
{{ $LIMIT_MESSAGES_CHECK_TOKEN := .Env.PROSODY_LIMIT_MESSAGES_CHECK_TOKEN | default "0" | toBool -}}
{{ $RATE_LIMIT_LOGIN_RATE := .Env.PROSODY_RATE_LIMIT_LOGIN_RATE | default "3" -}}
{{ $RATE_LIMIT_SESSION_RATE := .Env.PROSODY_RATE_LIMIT_SESSION_RATE | default "200" -}}
{{ $RATE_LIMIT_TIMEOUT := .Env.PROSODY_RATE_LIMIT_TIMEOUT | default "60" -}}
{{ $RATE_LIMIT_ALLOW_RANGES := .Env.PROSODY_RATE_LIMIT_ALLOW_RANGES | default "10.0.0.0/8" -}}
{{ $RATE_LIMIT_CACHE_SIZE := .Env.PROSODY_RATE_LIMIT_CACHE_SIZE | default "10000" -}}
{{ $REGION_NAME := .Env.PROSODY_REGION_NAME | default "default" -}}
{{ $RELEASE_NUMBER := .Env.RELEASE_NUMBER | default "" -}}
{{ $SHARD_NAME := .Env.SHARD | default "default" -}}
{{ $S2S_PORT := .Env.PROSODY_S2S_PORT | default "5269" -}}
{{ $VISITOR_INDEX := .Env.PROSODY_VISITOR_INDEX | default "0" -}}
{{ $VISITORS_MUC_PREFIX := .Env.PROSODY_VISITORS_MUC_PREFIX | default "muc" -}}
{{ $VISITORS_MAX_VISITORS_PER_NODE := .Env.VISITORS_MAX_VISITORS_PER_NODE | default "250" }}
{{ $VISITORS_XMPP_DOMAIN := .Env.VISITORS_XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $XMPP_AUTH_DOMAIN := .Env.XMPP_AUTH_DOMAIN | default "auth.meet.jitsi" -}}
{{ $XMPP_DOMAIN := .Env.XMPP_DOMAIN | default "meet.jitsi" -}}
{{ $XMPP_GUEST_DOMAIN := .Env.XMPP_GUEST_DOMAIN | default "guest.meet.jitsi" -}}
{{ $XMPP_MUC_DOMAIN := .Env.XMPP_MUC_DOMAIN | default "muc.meet.jitsi" -}}
{{ $XMPP_MUC_DOMAIN_PREFIX := (split "." $XMPP_MUC_DOMAIN)._0 -}}
{{ $XMPP_SERVER := .Env.XMPP_SERVER | default "xmpp.meet.jitsi" -}}
{{ $XMPP_SERVER_S2S_PORT := .Env.XMPP_SERVER_S2S_PORT | default $S2S_PORT -}}
{{ $XMPP_HIDDEN_DOMAIN := .Env.XMPP_HIDDEN_DOMAIN | default "hidden.meet.jitsi" -}}
plugin_paths = { "/prosody-plugins/", "/prosody-plugins-custom", "/prosody-plugins-contrib" }
muc_mapper_domain_base = "v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}";
muc_mapper_domain_prefix = "{{ $XMPP_MUC_DOMAIN_PREFIX }}";
http_default_host = "v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}"
main_domain = '{{ $XMPP_DOMAIN }}';
-- https://prosody.im/doc/modules/mod_smacks
smacks_max_unacked_stanzas = 5;
smacks_hibernation_time = 60;
-- this is dropped in 0.12
smacks_max_hibernated_sessions = 1;
smacks_max_old_sessions = 1;
unlimited_jids = { "focus@{{ $XMPP_AUTH_DOMAIN }}" }
limits = {
c2s = {
rate = "512kb/s";
};
s2sin = {
rate = "512kb/s";
};
}
authentication = 'internal_hashed'
storage = 'internal'
consider_websocket_secure = true;
consider_bosh_secure = true;
bosh_max_inactivity = 60;
-- this is added to make certs_s2soutinjection work
s2sout_override = {
["{{ $XMPP_MUC_DOMAIN }}"] = "tcp://{{ $XMPP_SERVER }}:{{ $XMPP_SERVER_S2S_PORT }}"; -- needed for visitors to send messages to main room
["{{ $XMPP_DOMAIN }}"] = "tcp://{{ $XMPP_SERVER }}:{{ $XMPP_SERVER_S2S_PORT }}";
["visitors.{{ $XMPP_DOMAIN }}"] = "tcp://{{ $XMPP_SERVER }}:{{ $XMPP_SERVER_S2S_PORT }}";
{{ if $ENABLE_GUEST_DOMAIN -}}
["{{ $XMPP_GUEST_DOMAIN }}"] = "tcp://{{ $XMPP_SERVER }}:{{ $XMPP_SERVER_S2S_PORT }}";
{{ end -}}
{{ if or $ENABLE_RECORDING $ENABLE_TRANSCRIPTIONS -}}
["{{ $XMPP_HIDDEN_DOMAIN }}"] = "tcp://{{ $XMPP_SERVER }}:{{ $XMPP_SERVER_S2S_PORT }}";
{{ end -}}
{{ if .Env.PROSODY_VISITORS_S2S_VHOSTS -}}
{{- range $index, $vhost := (splitList "," .Env.PROSODY_VISITORS_S2S_VHOSTS | compact) }}
["{{ $vhost }}"] = "tcp://{{ $XMPP_SERVER }}:{{ $XMPP_SERVER_S2S_PORT }}";
{{ end -}}
{{ end -}}
{{ if not $DISABLE_POLLS -}}
['polls.{{ $XMPP_DOMAIN }}'] = "tcp://{{ $XMPP_SERVER }}:{{ $XMPP_SERVER_S2S_PORT }}";
{{ end -}}
}
muc_limit_messages_count = 10;
muc_limit_messages_check_token = {{ $LIMIT_MESSAGES_CHECK_TOKEN }};
----------- Virtual hosts -----------
VirtualHost 'v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}'
authentication = 'jitsi-anonymous'
ssl = {
key = "/config/certs/v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}.key";
certificate = "/config/certs/v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}.crt";
}
modules_enabled = {
'bosh';
"external_services";
{{ if $ENABLE_XMPP_WEBSOCKET -}}
"websocket";
"smacks"; -- XEP-0198: Stream Management
{{ end -}}
{{ if .Env.XMPP_MODULES }}
"{{ join "\";\n\"" (splitList "," .Env.XMPP_MODULES | compact) }}";
{{ end }}
'features_identity';
}
main_muc = '{{ $VISITORS_MUC_PREFIX }}.v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}';
shard_name = "{{ $SHARD_NAME }}"
region_name = "{{ $REGION_NAME }}"
release_number = "{{ $RELEASE_NUMBER }}"
{{ if .Env.XMPP_CONFIGURATION -}}
{{ join "\n " (splitList "," .Env.XMPP_CONFIGURATION | compact) }}
{{- end }}
VirtualHost '{{ $XMPP_AUTH_DOMAIN }}'
modules_enabled = {
'limits_exception';
'smacks';
}
authentication = 'internal_hashed'
smacks_hibernation_time = 15;
Component '{{ $VISITORS_MUC_PREFIX }}.v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}' 'muc'
storage = 'memory'
muc_room_cache_size = 10000
restrict_room_creation = true
modules_enabled = {
"muc_hide_all";
"muc_meeting_id";
'fmuc';
's2s_bidi';
's2s_whitelist';
's2sout_override';
'muc_max_occupants';
{{ if $ENABLE_SUBDOMAINS -}}
"muc_domain_mapper";
{{ end -}}
{{ if $ENABLE_RATE_LIMITS -}}
"muc_rate_limit";
"rate_limit";
{{ end -}}
{{ if .Env.XMPP_MUC_MODULES -}}
"{{ join "\";\n\"" (splitList "," .Env.XMPP_MUC_MODULES | compact) }}";
{{ end -}}
}
muc_room_default_presence_broadcast = {
visitor = false;
participant = true;
moderator = true;
};
muc_room_locking = false
muc_room_default_public_jids = true
muc_max_occupants = {{ $VISITORS_MAX_VISITORS_PER_NODE}}
muc_access_whitelist = {
"{{ $XMPP_DOMAIN }}";
}
muc_tombstones = false
muc_room_allow_persistent = false
{{ if $ENABLE_RATE_LIMITS -}}
-- Max allowed join/login rate in events per second.
rate_limit_login_rate = {{ $RATE_LIMIT_LOGIN_RATE }};
-- The rate to which sessions from IPs exceeding the join rate will be limited, in bytes per second.
rate_limit_session_rate = {{ $RATE_LIMIT_SESSION_RATE }};
-- The time in seconds, after which the limit for an IP address is lifted.
rate_limit_timeout = {{ $RATE_LIMIT_TIMEOUT }};
-- List of regular expressions for IP addresses that are not limited by this module.
rate_limit_whitelist = {
"127.0.0.1";
{{ range $index, $cidr := (splitList "," $RATE_LIMIT_ALLOW_RANGES) -}}
"{{ $cidr }}";
{{ end -}}
};
rate_limit_whitelist_jids = {
"{{ $JIBRI_RECORDER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}",
"{{ $JIGASI_TRANSCRIBER_USER }}@{{ $XMPP_HIDDEN_DOMAIN }}"
}
{{ end -}}
-- The size of the cache that saves state for IP addresses
rate_limit_cache_size = {{ $RATE_LIMIT_CACHE_SIZE }};
muc_rate_joins = 30;
{{ if .Env.XMPP_MUC_CONFIGURATION -}}
{{ join "\n" (splitList "," .Env.XMPP_MUC_CONFIGURATION | compact) }}
{{ end -}}
{{ if not $DISABLE_POLLS -}}
Component 'polls.v{{ $VISITOR_INDEX }}.{{ $VISITORS_XMPP_DOMAIN }}' 'polls_component'
{{ end -}}

Some files were not shown because too many files have changed in this diff Show More