Add local Jitsi Docker staging setup
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Local Docker Jitsi runtime. Generated by scripts/local-jitsi-setup.sh.
|
||||||
|
local/docker-jitsi-meet/
|
||||||
|
local/.jitsi-meet-cfg/
|
||||||
|
local/*.zip
|
||||||
|
local/.release
|
||||||
|
|
||||||
|
# Local-only shell/environment files.
|
||||||
|
local/.env
|
||||||
|
local/*.local
|
||||||
43
README.md
43
README.md
@@ -18,10 +18,20 @@ jitsi/
|
|||||||
public/politictalk/
|
public/politictalk/
|
||||||
branding.json
|
branding.json
|
||||||
pgLogo.svg
|
pgLogo.svg
|
||||||
|
pg_bg.png
|
||||||
|
local/
|
||||||
|
README.md
|
||||||
|
custom-config.js
|
||||||
|
custom-interface_config.js
|
||||||
|
docker-compose.override.yml
|
||||||
nginx/
|
nginx/
|
||||||
politictalk.parallelglobe.io.conf
|
politictalk.parallelglobe.io.conf
|
||||||
scripts/
|
scripts/
|
||||||
deploy-vps.sh
|
deploy-vps.sh
|
||||||
|
local-jitsi-setup.sh
|
||||||
|
local-jitsi-start.sh
|
||||||
|
local-jitsi-stop.sh
|
||||||
|
local-jitsi-sync.sh
|
||||||
templates/
|
templates/
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -38,6 +48,39 @@ jitsi/
|
|||||||
- E2EE support is enabled in the Jitsi config.
|
- E2EE support is enabled in the Jitsi config.
|
||||||
- The logo and dynamic branding point to PoliticTalk public assets.
|
- The logo and dynamic branding point to PoliticTalk public assets.
|
||||||
|
|
||||||
|
## Local Docker Testing
|
||||||
|
|
||||||
|
Local Jitsi testing uses the official Docker Jitsi release. The downloaded Docker files and generated runtime config are ignored by Git, while PoliticTalk overrides stay tracked in this repo.
|
||||||
|
|
||||||
|
First install and start Docker Desktop. Then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/amardeep/work/pg/jitsi
|
||||||
|
./scripts/local-jitsi-setup.sh
|
||||||
|
./scripts/local-jitsi-start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Open:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://localhost:8443/pt-local-test
|
||||||
|
```
|
||||||
|
|
||||||
|
The local browser may show a self-signed certificate warning. That is expected.
|
||||||
|
|
||||||
|
When editing local override files or assets:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/local-jitsi-sync.sh
|
||||||
|
./scripts/local-jitsi-restart-web.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
To stop local Jitsi:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/local-jitsi-stop.sh
|
||||||
|
```
|
||||||
|
|
||||||
## VPS Paths
|
## VPS Paths
|
||||||
|
|
||||||
The deploy script copies local files into these VPS paths:
|
The deploy script copies local files into these VPS paths:
|
||||||
|
|||||||
57
local/README.md
Normal file
57
local/README.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Local PoliticTalk Jitsi
|
||||||
|
|
||||||
|
This folder contains the tracked overrides used to test PoliticTalk Jitsi locally with the official Docker Jitsi stack.
|
||||||
|
|
||||||
|
The downloaded Docker stack and generated runtime config are intentionally ignored by Git:
|
||||||
|
|
||||||
|
```text
|
||||||
|
local/docker-jitsi-meet/
|
||||||
|
local/.jitsi-meet-cfg/
|
||||||
|
```
|
||||||
|
|
||||||
|
## First Run
|
||||||
|
|
||||||
|
Install Docker Desktop first if `docker --version` is not available.
|
||||||
|
|
||||||
|
Then run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/amardeep/work/pg/jitsi
|
||||||
|
./scripts/local-jitsi-setup.sh
|
||||||
|
./scripts/local-jitsi-start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Open:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://localhost:8443/pt-local-test
|
||||||
|
```
|
||||||
|
|
||||||
|
The browser may warn about a self-signed certificate. That is expected for local Docker testing.
|
||||||
|
|
||||||
|
## After Editing Overrides
|
||||||
|
|
||||||
|
When you edit `local/custom-config.js`, `local/custom-interface_config.js`, or local assets, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/local-jitsi-sync.sh
|
||||||
|
./scripts/local-jitsi-restart-web.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Stop
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/local-jitsi-stop.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## What This Tests
|
||||||
|
|
||||||
|
- PoliticTalk branding assets
|
||||||
|
- prejoin behavior
|
||||||
|
- audio-only policy
|
||||||
|
- muted microphone/camera startup
|
||||||
|
- toolbar restrictions
|
||||||
|
- chat, polls, raise hand, fullscreen, noise suppression
|
||||||
|
- E2EE UI availability
|
||||||
|
|
||||||
|
Final production verification still happens on the VPS because real WebRTC networking, domain, HTTPS, and future JWT auth depend on the server environment.
|
||||||
70
local/custom-config.js
Normal file
70
local/custom-config.js
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
// PoliticTalk local Docker overrides.
|
||||||
|
// Docker Jitsi appends this file after generating /config/config.js.
|
||||||
|
|
||||||
|
config.defaultLogoUrl = '/images/politictalk/pgLogo.svg';
|
||||||
|
config.dynamicBrandingUrl = '/images/politictalk/branding.json';
|
||||||
|
|
||||||
|
config.startAudioOnly = true;
|
||||||
|
config.startAudioMuted = 0;
|
||||||
|
config.startWithAudioMuted = true;
|
||||||
|
config.startVideoMuted = 0;
|
||||||
|
config.startWithVideoMuted = true;
|
||||||
|
|
||||||
|
config.disableSelfView = true;
|
||||||
|
config.disableSelfViewSettings = true;
|
||||||
|
config.disableLocalVideoFlip = true;
|
||||||
|
|
||||||
|
config.disableChat = false;
|
||||||
|
config.disablePolls = false;
|
||||||
|
config.disableInviteFunctions = true;
|
||||||
|
config.doNotStoreRoom = true;
|
||||||
|
|
||||||
|
config.enableEncodedTransformSupport = true;
|
||||||
|
config.enableNoisyMicDetection = true;
|
||||||
|
config.disableRemoteMute = false;
|
||||||
|
|
||||||
|
config.prejoinConfig = {
|
||||||
|
enabled: true,
|
||||||
|
hideDisplayName: false,
|
||||||
|
hideExtraJoinButtons: ['no-audio', 'by-phone'],
|
||||||
|
preCallTestEnabled: false,
|
||||||
|
preCallTestICEUrl: '',
|
||||||
|
showHangUp: true
|
||||||
|
};
|
||||||
|
|
||||||
|
config.toolbarButtons = [
|
||||||
|
'microphone',
|
||||||
|
'chat',
|
||||||
|
'raisehand',
|
||||||
|
'fullscreen',
|
||||||
|
'noisesuppression',
|
||||||
|
'participants-pane',
|
||||||
|
'hangup'
|
||||||
|
];
|
||||||
|
|
||||||
|
config.hiddenPremeetingButtons = [
|
||||||
|
'microphone',
|
||||||
|
'camera',
|
||||||
|
'select-background',
|
||||||
|
'invite',
|
||||||
|
'settings'
|
||||||
|
];
|
||||||
|
|
||||||
|
config.participantsPane = {
|
||||||
|
enabled: true,
|
||||||
|
hideModeratorSettingsTab: false,
|
||||||
|
hideMoreActionsButton: false,
|
||||||
|
hideMuteAllButton: false
|
||||||
|
};
|
||||||
|
|
||||||
|
config.e2ee = {
|
||||||
|
externallyManagedKey: false,
|
||||||
|
disabled: false,
|
||||||
|
labels: {
|
||||||
|
label: 'End-to-end encryption',
|
||||||
|
description: 'End-to-end encryption protects media between participants.',
|
||||||
|
tooltip: 'End-to-end encryption',
|
||||||
|
warning: 'Some features may be limited while encryption is enabled.'
|
||||||
|
}
|
||||||
|
};
|
||||||
22
local/custom-interface_config.js
Normal file
22
local/custom-interface_config.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
// PoliticTalk local Docker interface overrides.
|
||||||
|
// Docker Jitsi appends this file after generating /config/interface_config.js.
|
||||||
|
|
||||||
|
interfaceConfig.APP_NAME = 'PoliticTalk';
|
||||||
|
interfaceConfig.NATIVE_APP_NAME = 'PoliticTalk';
|
||||||
|
interfaceConfig.PROVIDER_NAME = 'ParallelGlobe';
|
||||||
|
|
||||||
|
interfaceConfig.DEFAULT_WELCOME_PAGE_LOGO_URL = '/images/politictalk/pgLogo.svg';
|
||||||
|
interfaceConfig.SHOW_JITSI_WATERMARK = false;
|
||||||
|
interfaceConfig.SHOW_BRAND_WATERMARK = true;
|
||||||
|
interfaceConfig.BRAND_WATERMARK_LINK = 'https://parallelglobe.io/';
|
||||||
|
interfaceConfig.SHOW_POWERED_BY = false;
|
||||||
|
interfaceConfig.MOBILE_APP_PROMO = false;
|
||||||
|
|
||||||
|
interfaceConfig.DISPLAY_WELCOME_FOOTER = false;
|
||||||
|
interfaceConfig.DISPLAY_WELCOME_PAGE_CONTENT = false;
|
||||||
|
interfaceConfig.DISPLAY_WELCOME_PAGE_ADDITIONAL_CARD = false;
|
||||||
|
interfaceConfig.DISPLAY_WELCOME_PAGE_TOOLBAR_ADDITIONAL_CONTENT = false;
|
||||||
|
|
||||||
|
interfaceConfig.JITSI_WATERMARK_LINK = '';
|
||||||
|
interfaceConfig.SUPPORT_URL = '';
|
||||||
4
local/docker-compose.override.yml
Normal file
4
local/docker-compose.override.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
services:
|
||||||
|
web:
|
||||||
|
volumes:
|
||||||
|
- ../../assets/public/politictalk:/usr/share/jitsi-meet/images/politictalk:ro
|
||||||
14
scripts/local-jitsi-logs.sh
Executable file
14
scripts/local-jitsi-logs.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
STACK_DIR="$ROOT_DIR/local/docker-jitsi-meet"
|
||||||
|
|
||||||
|
if [[ ! -d "$STACK_DIR" ]]; then
|
||||||
|
echo "Missing $STACK_DIR. Run ./scripts/local-jitsi-setup.sh first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$STACK_DIR"
|
||||||
|
docker compose logs -f "${@}"
|
||||||
16
scripts/local-jitsi-restart-web.sh
Executable file
16
scripts/local-jitsi-restart-web.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
STACK_DIR="$ROOT_DIR/local/docker-jitsi-meet"
|
||||||
|
|
||||||
|
if [[ ! -d "$STACK_DIR" ]]; then
|
||||||
|
echo "Missing $STACK_DIR. Run ./scripts/local-jitsi-setup.sh first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$SCRIPT_DIR/local-jitsi-sync.sh"
|
||||||
|
|
||||||
|
cd "$STACK_DIR"
|
||||||
|
docker compose restart web
|
||||||
109
scripts/local-jitsi-setup.sh
Executable file
109
scripts/local-jitsi-setup.sh
Executable file
@@ -0,0 +1,109 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
LOCAL_DIR="$ROOT_DIR/local"
|
||||||
|
STACK_DIR="$LOCAL_DIR/docker-jitsi-meet"
|
||||||
|
CONFIG_DIR="$LOCAL_DIR/.jitsi-meet-cfg"
|
||||||
|
RELEASE_FILE="$LOCAL_DIR/.release"
|
||||||
|
|
||||||
|
HTTP_PORT="${HTTP_PORT:-8000}"
|
||||||
|
HTTPS_PORT="${HTTPS_PORT:-8443}"
|
||||||
|
PUBLIC_URL="${PUBLIC_URL:-https://localhost:${HTTPS_PORT}}"
|
||||||
|
TZ="${TZ:-Asia/Kolkata}"
|
||||||
|
|
||||||
|
set_env() {
|
||||||
|
local key="$1"
|
||||||
|
local value="$2"
|
||||||
|
local file="$STACK_DIR/.env"
|
||||||
|
|
||||||
|
if grep -qE "^#?${key}=" "$file"; then
|
||||||
|
perl -0pi -e "s|^#?${key}=.*|${key}=${value}|m" "$file"
|
||||||
|
else
|
||||||
|
printf '%s=%s\n' "$key" "$value" >> "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p "$LOCAL_DIR"
|
||||||
|
|
||||||
|
if [[ ! -d "$STACK_DIR" || "${FORCE:-0}" == "1" ]]; then
|
||||||
|
rm -rf "$STACK_DIR"
|
||||||
|
|
||||||
|
tmp_dir="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$tmp_dir"' EXIT
|
||||||
|
|
||||||
|
release_json="$(curl -fsSL https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest)"
|
||||||
|
tag_name="$(printf '%s' "$release_json" | sed -n 's/.*"tag_name": "\([^"]*\)".*/\1/p' | head -1)"
|
||||||
|
zip_url="$(printf '%s' "$release_json" | sed -n 's/.*"zipball_url": "\([^"]*\)".*/\1/p' | head -1)"
|
||||||
|
|
||||||
|
if [[ -z "$zip_url" || -z "$tag_name" ]]; then
|
||||||
|
echo "Could not detect latest docker-jitsi-meet release from GitHub."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -LfsS "$zip_url" -o "$tmp_dir/docker-jitsi-meet.zip"
|
||||||
|
unzip -q "$tmp_dir/docker-jitsi-meet.zip" -d "$tmp_dir"
|
||||||
|
|
||||||
|
extracted_dir="$(find "$tmp_dir" -maxdepth 1 -type d -name 'jitsi-docker-jitsi-meet-*' | head -1)"
|
||||||
|
if [[ -z "$extracted_dir" ]]; then
|
||||||
|
echo "Could not find extracted docker-jitsi-meet directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv "$extracted_dir" "$STACK_DIR"
|
||||||
|
printf '%s\n' "$tag_name" > "$RELEASE_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
created_env=0
|
||||||
|
if [[ ! -f "$STACK_DIR/.env" ]]; then
|
||||||
|
cp "$STACK_DIR/env.example" "$STACK_DIR/.env"
|
||||||
|
created_env=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set_env CONFIG "$CONFIG_DIR"
|
||||||
|
set_env TZ "$TZ"
|
||||||
|
set_env HTTP_PORT "$HTTP_PORT"
|
||||||
|
set_env HTTPS_PORT "$HTTPS_PORT"
|
||||||
|
set_env PUBLIC_URL "$PUBLIC_URL"
|
||||||
|
|
||||||
|
set_env ENABLE_PREJOIN_PAGE 1
|
||||||
|
set_env ENABLE_WELCOME_PAGE 1
|
||||||
|
set_env ENABLE_NOISY_MIC_DETECTION 1
|
||||||
|
set_env ENABLE_NO_AUDIO_DETECTION 1
|
||||||
|
set_env ENABLE_AV_MODERATION 1
|
||||||
|
set_env ENABLE_LOBBY 1
|
||||||
|
|
||||||
|
set_env START_AUDIO_ONLY 1
|
||||||
|
set_env START_AUDIO_MUTED 0
|
||||||
|
set_env START_WITH_AUDIO_MUTED 1
|
||||||
|
set_env START_VIDEO_MUTED 0
|
||||||
|
set_env START_WITH_VIDEO_MUTED 1
|
||||||
|
|
||||||
|
set_env DISABLE_POLLS 0
|
||||||
|
set_env DISABLE_DEEP_LINKING 1
|
||||||
|
set_env DYNAMIC_BRANDING_URL /images/politictalk/branding.json
|
||||||
|
set_env TOOLBAR_BUTTONS microphone,chat,raisehand,fullscreen,noisesuppression,participants-pane,hangup
|
||||||
|
set_env HIDE_PREMEETING_BUTTONS microphone,camera,select-background,invite,settings
|
||||||
|
set_env HIDE_PREJOIN_EXTRA_BUTTONS no-audio,by-phone
|
||||||
|
|
||||||
|
mkdir -p "$CONFIG_DIR"/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
|
||||||
|
|
||||||
|
if [[ "$created_env" == "1" || "${REGENERATE_PASSWORDS:-0}" == "1" ]]; then
|
||||||
|
(
|
||||||
|
cd "$STACK_DIR"
|
||||||
|
./gen-passwords.sh
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$SCRIPT_DIR/local-jitsi-sync.sh"
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
Local Docker Jitsi is prepared.
|
||||||
|
|
||||||
|
Next:
|
||||||
|
./scripts/local-jitsi-start.sh
|
||||||
|
|
||||||
|
Then open:
|
||||||
|
$PUBLIC_URL/pt-local-test
|
||||||
|
EOF
|
||||||
28
scripts/local-jitsi-start.sh
Executable file
28
scripts/local-jitsi-start.sh
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
STACK_DIR="$ROOT_DIR/local/docker-jitsi-meet"
|
||||||
|
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "Docker is not installed or not available in PATH. Install Docker Desktop, start it, then rerun this script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
|
echo "Docker Compose v2 is not available. Install/update Docker Desktop, then rerun this script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$STACK_DIR" ]]; then
|
||||||
|
"$SCRIPT_DIR/local-jitsi-setup.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$SCRIPT_DIR/local-jitsi-sync.sh"
|
||||||
|
|
||||||
|
cd "$STACK_DIR"
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
echo "Local PoliticTalk Jitsi is starting."
|
||||||
|
echo "Open: https://localhost:8443/pt-local-test"
|
||||||
14
scripts/local-jitsi-stop.sh
Executable file
14
scripts/local-jitsi-stop.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
STACK_DIR="$ROOT_DIR/local/docker-jitsi-meet"
|
||||||
|
|
||||||
|
if [[ ! -d "$STACK_DIR" ]]; then
|
||||||
|
echo "Local Docker Jitsi stack is not set up yet."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$STACK_DIR"
|
||||||
|
docker compose down
|
||||||
21
scripts/local-jitsi-sync.sh
Executable file
21
scripts/local-jitsi-sync.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
LOCAL_DIR="$ROOT_DIR/local"
|
||||||
|
STACK_DIR="$LOCAL_DIR/docker-jitsi-meet"
|
||||||
|
CONFIG_DIR="$LOCAL_DIR/.jitsi-meet-cfg"
|
||||||
|
|
||||||
|
if [[ ! -d "$STACK_DIR" ]]; then
|
||||||
|
echo "Missing $STACK_DIR. Run ./scripts/local-jitsi-setup.sh first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$CONFIG_DIR"/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
|
||||||
|
|
||||||
|
cp "$LOCAL_DIR/custom-config.js" "$CONFIG_DIR/web/custom-config.js"
|
||||||
|
cp "$LOCAL_DIR/custom-interface_config.js" "$CONFIG_DIR/web/custom-interface_config.js"
|
||||||
|
cp "$LOCAL_DIR/docker-compose.override.yml" "$STACK_DIR/docker-compose.override.yml"
|
||||||
|
|
||||||
|
echo "Synced PoliticTalk local overrides into Docker Jitsi runtime."
|
||||||
Reference in New Issue
Block a user