From 8997f4804fd80e0b605c9c499ca5393ad3585a5e Mon Sep 17 00:00:00 2001 From: Amardeep Date: Thu, 14 May 2026 23:35:52 +0530 Subject: [PATCH] Add local Jitsi Docker staging setup --- .gitignore | 9 +++ README.md | 43 ++++++++++++ local/README.md | 57 +++++++++++++++ local/custom-config.js | 70 ++++++++++++++++++ local/custom-interface_config.js | 22 ++++++ local/docker-compose.override.yml | 4 ++ scripts/local-jitsi-logs.sh | 14 ++++ scripts/local-jitsi-restart-web.sh | 16 +++++ scripts/local-jitsi-setup.sh | 109 +++++++++++++++++++++++++++++ scripts/local-jitsi-start.sh | 28 ++++++++ scripts/local-jitsi-stop.sh | 14 ++++ scripts/local-jitsi-sync.sh | 21 ++++++ 12 files changed, 407 insertions(+) create mode 100644 .gitignore create mode 100644 local/README.md create mode 100644 local/custom-config.js create mode 100644 local/custom-interface_config.js create mode 100644 local/docker-compose.override.yml create mode 100755 scripts/local-jitsi-logs.sh create mode 100755 scripts/local-jitsi-restart-web.sh create mode 100755 scripts/local-jitsi-setup.sh create mode 100755 scripts/local-jitsi-start.sh create mode 100755 scripts/local-jitsi-stop.sh create mode 100755 scripts/local-jitsi-sync.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6fb67f7 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/README.md b/README.md index a69694c..64ec739 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,20 @@ jitsi/ public/politictalk/ branding.json pgLogo.svg + pg_bg.png + local/ + README.md + custom-config.js + custom-interface_config.js + docker-compose.override.yml nginx/ politictalk.parallelglobe.io.conf scripts/ deploy-vps.sh + local-jitsi-setup.sh + local-jitsi-start.sh + local-jitsi-stop.sh + local-jitsi-sync.sh templates/ ``` @@ -38,6 +48,39 @@ jitsi/ - E2EE support is enabled in the Jitsi config. - 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 The deploy script copies local files into these VPS paths: diff --git a/local/README.md b/local/README.md new file mode 100644 index 0000000..78b0e1d --- /dev/null +++ b/local/README.md @@ -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. diff --git a/local/custom-config.js b/local/custom-config.js new file mode 100644 index 0000000..643e330 --- /dev/null +++ b/local/custom-config.js @@ -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.' + } +}; diff --git a/local/custom-interface_config.js b/local/custom-interface_config.js new file mode 100644 index 0000000..524490f --- /dev/null +++ b/local/custom-interface_config.js @@ -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 = ''; diff --git a/local/docker-compose.override.yml b/local/docker-compose.override.yml new file mode 100644 index 0000000..999b481 --- /dev/null +++ b/local/docker-compose.override.yml @@ -0,0 +1,4 @@ +services: + web: + volumes: + - ../../assets/public/politictalk:/usr/share/jitsi-meet/images/politictalk:ro diff --git a/scripts/local-jitsi-logs.sh b/scripts/local-jitsi-logs.sh new file mode 100755 index 0000000..456bf3e --- /dev/null +++ b/scripts/local-jitsi-logs.sh @@ -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 "${@}" diff --git a/scripts/local-jitsi-restart-web.sh b/scripts/local-jitsi-restart-web.sh new file mode 100755 index 0000000..e64d9f0 --- /dev/null +++ b/scripts/local-jitsi-restart-web.sh @@ -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 diff --git a/scripts/local-jitsi-setup.sh b/scripts/local-jitsi-setup.sh new file mode 100755 index 0000000..713f282 --- /dev/null +++ b/scripts/local-jitsi-setup.sh @@ -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 </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" diff --git a/scripts/local-jitsi-stop.sh b/scripts/local-jitsi-stop.sh new file mode 100755 index 0000000..77baf96 --- /dev/null +++ b/scripts/local-jitsi-stop.sh @@ -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 diff --git a/scripts/local-jitsi-sync.sh b/scripts/local-jitsi-sync.sh new file mode 100755 index 0000000..74dd080 --- /dev/null +++ b/scripts/local-jitsi-sync.sh @@ -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."