From a3f2df9045f34bc56edefd553b08d5ca665fca36 Mon Sep 17 00:00:00 2001 From: Jerry Aldrich Date: Thu, 1 Apr 2021 22:50:07 -0700 Subject: [PATCH] Initial commit --- .gitignore | 4 + CHANGELOG.md | 317 +++++++++++++++ LICENSE | 203 ++++++++++ Makefile | 42 ++ README.md | 19 + base-java/Dockerfile | 12 + base/Dockerfile | 27 ++ base/rootfs/etc/apt/apt.conf.d/99local | 2 + base/rootfs/etc/cont-finish.d/.gitkeep | 0 base/rootfs/etc/cont-init.d/.gitkeep | 0 base/rootfs/etc/cont-init.d/01-set-timezone | 10 + base/rootfs/etc/fix-attrs.d/.gitkeep | 0 base/rootfs/etc/services.d/.gitkeep | 0 base/rootfs/fix-permissions.sh | 7 + base/rootfs/install-devtools.sh | 10 + base/rootfs/pre-init.sh | 16 + base/rootfs/usr/bin/apt-cleanup | 3 + base/rootfs/usr/bin/apt-dpkg-wrap | 8 + base/rootfs/usr/bin/tpl | 4 + docker-compose.yml | 257 ++++++++++++ env.example | 381 ++++++++++++++++++ etherpad.yml | 16 + examples/README.md | 11 + examples/kubernetes/README.md | 26 ++ examples/kubernetes/deployment.yaml | 145 +++++++ examples/kubernetes/jvb-service.yaml | 17 + examples/kubernetes/web-service.yaml | 32 ++ examples/traefik-v2/README.md | 18 + examples/traefik-v2/docker-compose.yml | 269 +++++++++++++ examples/traefik/README.md | 17 + examples/traefik/docker-compose.yml | 180 +++++++++ gen-passwords.sh | 21 + jibri.yml | 36 ++ jibri/Dockerfile | 53 +++ jibri/rootfs/defaults/config.json | 60 +++ jibri/rootfs/defaults/logging.properties | 33 ++ jibri/rootfs/etc/cont-init.d/10-config | 60 +++ .../policies/managed/managed_policies.json | 4 + jibri/rootfs/etc/services.d/10-xorg/run | 5 + jibri/rootfs/etc/services.d/20-icewm/run | 5 + jibri/rootfs/etc/services.d/30-jibri/run | 9 + jicofo/Dockerfile | 15 + jicofo/rootfs/defaults/jicofo.conf | 143 +++++++ jicofo/rootfs/defaults/logging.properties | 21 + jicofo/rootfs/etc/cont-init.d/10-config | 24 ++ jicofo/rootfs/etc/services.d/jicofo/run | 8 + jigasi.yml | 50 +++ jigasi/Dockerfile | 17 + jigasi/rootfs/defaults/logging.properties | 18 + .../defaults/sip-communicator.properties | 150 +++++++ jigasi/rootfs/etc/cont-init.d/10-config | 50 +++ jigasi/rootfs/etc/services.d/jigasi/run | 9 + jvb/Dockerfile | 15 + jvb/rootfs/defaults/jvb.conf | 65 +++ jvb/rootfs/defaults/logging.properties | 14 + .../defaults/sip-communicator.properties | 5 + jvb/rootfs/etc/cont-init.d/10-config | 25 ++ jvb/rootfs/etc/services.d/jvb/run | 7 + prosody/Dockerfile | 70 ++++ .../rootfs/defaults/conf.d/jitsi-meet.cfg.lua | 184 +++++++++ prosody/rootfs/defaults/prosody.cfg.lua | 172 ++++++++ prosody/rootfs/defaults/saslauthd.conf | 26 ++ prosody/rootfs/etc/cont-init.d/10-config | 78 ++++ prosody/rootfs/etc/sasl/xmpp.conf | 2 + .../rootfs/etc/services.d/10-saslauthd/run | 2 + prosody/rootfs/etc/services.d/prosody/run | 3 + .../prosodyctl-certdir-permission-fix.patch | 27 ++ release.sh | 72 ++++ resources/docker-jitsi-meet.png | Bin 0 -> 124909 bytes resources/docker-jitsi-meet.xml | 1 + resources/jitsi-docker.png | Bin 0 -> 64130 bytes web/Dockerfile | 24 ++ web/rootfs/defaults/default | 26 ++ web/rootfs/defaults/ffdhe2048.txt | 8 + web/rootfs/defaults/meet.conf | 92 +++++ web/rootfs/defaults/nginx.conf | 67 +++ web/rootfs/defaults/settings-config.js | 306 ++++++++++++++ web/rootfs/defaults/ssl.conf | 28 ++ web/rootfs/defaults/system-config.js | 50 +++ web/rootfs/etc/cont-init.d/10-config | 95 +++++ web/rootfs/etc/services.d/cron/run | 10 + web/rootfs/etc/services.d/nginx/run | 3 + 82 files changed, 4321 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 base-java/Dockerfile create mode 100644 base/Dockerfile create mode 100644 base/rootfs/etc/apt/apt.conf.d/99local create mode 100644 base/rootfs/etc/cont-finish.d/.gitkeep create mode 100644 base/rootfs/etc/cont-init.d/.gitkeep create mode 100755 base/rootfs/etc/cont-init.d/01-set-timezone create mode 100644 base/rootfs/etc/fix-attrs.d/.gitkeep create mode 100644 base/rootfs/etc/services.d/.gitkeep create mode 100755 base/rootfs/fix-permissions.sh create mode 100755 base/rootfs/install-devtools.sh create mode 100755 base/rootfs/pre-init.sh create mode 100755 base/rootfs/usr/bin/apt-cleanup create mode 100755 base/rootfs/usr/bin/apt-dpkg-wrap create mode 100755 base/rootfs/usr/bin/tpl create mode 100644 docker-compose.yml create mode 100644 env.example create mode 100644 etherpad.yml create mode 100644 examples/README.md create mode 100644 examples/kubernetes/README.md create mode 100644 examples/kubernetes/deployment.yaml create mode 100644 examples/kubernetes/jvb-service.yaml create mode 100644 examples/kubernetes/web-service.yaml create mode 100644 examples/traefik-v2/README.md create mode 100644 examples/traefik-v2/docker-compose.yml create mode 100644 examples/traefik/README.md create mode 100644 examples/traefik/docker-compose.yml create mode 100755 gen-passwords.sh create mode 100644 jibri.yml create mode 100644 jibri/Dockerfile create mode 100644 jibri/rootfs/defaults/config.json create mode 100644 jibri/rootfs/defaults/logging.properties create mode 100644 jibri/rootfs/etc/cont-init.d/10-config create mode 100644 jibri/rootfs/etc/opt/chrome/policies/managed/managed_policies.json create mode 100644 jibri/rootfs/etc/services.d/10-xorg/run create mode 100644 jibri/rootfs/etc/services.d/20-icewm/run create mode 100644 jibri/rootfs/etc/services.d/30-jibri/run create mode 100644 jicofo/Dockerfile create mode 100644 jicofo/rootfs/defaults/jicofo.conf create mode 100644 jicofo/rootfs/defaults/logging.properties create mode 100644 jicofo/rootfs/etc/cont-init.d/10-config create mode 100644 jicofo/rootfs/etc/services.d/jicofo/run create mode 100644 jigasi.yml create mode 100644 jigasi/Dockerfile create mode 100644 jigasi/rootfs/defaults/logging.properties create mode 100644 jigasi/rootfs/defaults/sip-communicator.properties create mode 100644 jigasi/rootfs/etc/cont-init.d/10-config create mode 100644 jigasi/rootfs/etc/services.d/jigasi/run create mode 100644 jvb/Dockerfile create mode 100644 jvb/rootfs/defaults/jvb.conf create mode 100644 jvb/rootfs/defaults/logging.properties create mode 100644 jvb/rootfs/defaults/sip-communicator.properties create mode 100644 jvb/rootfs/etc/cont-init.d/10-config create mode 100644 jvb/rootfs/etc/services.d/jvb/run create mode 100644 prosody/Dockerfile create mode 100644 prosody/rootfs/defaults/conf.d/jitsi-meet.cfg.lua create mode 100644 prosody/rootfs/defaults/prosody.cfg.lua create mode 100644 prosody/rootfs/defaults/saslauthd.conf create mode 100755 prosody/rootfs/etc/cont-init.d/10-config create mode 100644 prosody/rootfs/etc/sasl/xmpp.conf create mode 100755 prosody/rootfs/etc/services.d/10-saslauthd/run create mode 100755 prosody/rootfs/etc/services.d/prosody/run create mode 100644 prosody/rootfs/prosodyctl-certdir-permission-fix.patch create mode 100755 release.sh create mode 100644 resources/docker-jitsi-meet.png create mode 100644 resources/docker-jitsi-meet.xml create mode 100644 resources/jitsi-docker.png create mode 100644 web/Dockerfile create mode 100644 web/rootfs/defaults/default create mode 100644 web/rootfs/defaults/ffdhe2048.txt create mode 100644 web/rootfs/defaults/meet.conf create mode 100644 web/rootfs/defaults/nginx.conf create mode 100644 web/rootfs/defaults/settings-config.js create mode 100644 web/rootfs/defaults/ssl.conf create mode 100644 web/rootfs/defaults/system-config.js create mode 100644 web/rootfs/etc/cont-init.d/10-config create mode 100755 web/rootfs/etc/services.d/cron/run create mode 100644 web/rootfs/etc/services.d/nginx/run diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85cf233 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.swp +.env +.env.bak +docker-compose.override.yml diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..aefa896 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,317 @@ +## stable-5390-3 + +Based on stable release 5390-3. + +* a698da5 misc: add jicofo reservation env variables to compose +* 86c3022 web: brandingDataUrl -> dynamicBrandingUrl +* 88e950d jicofo: fix healthcheck +* 493cbdd misc: fix typo +* e12d7f2 web : Add DESKTOP_SHARING_FRAMERATE_MIN and MAX env vars +* fa98a31 examples: fix k8s example +* 88d1034 doc: add port to PUBLIC_URL +* c876b40 doc: update CHANGELOG +* 5cf14b0 misc: working on latest + +## stable-5390-2 + +Based on stable release 5390-2. + +* 3e04fb4 prosody: fix lobby when authentication is enabled +* 24781e3 misc: working on latest + +## stable-5390-1 + +Based on stable release 5390-1. + +* 3ac5397 misc: working on latest + +## stable-5390 + +Based on stable release 5390. + +* 0f541c8 jicofo: migrate to new config +* 12823cb prosody: fix jibri recording websocket error +* 7594ea2 jigasi: add ability to control SIP default room for incoming calls +* b0e653a jigasi: fix when using authentication +* 4564170 misc: working on latest + +## stable-5142-4 + +Based on stable release 5142-4. + +* 6f7b2b4 prosody: add internal domain name to default cross-domains list +* ada7b95 jvb: fix check for JVB_TCP_HARVESTER_DISABLED +* a7fb101 jibri: don't provide a non-existing finalizer path +* d013053 jibri: add missing dependency for `kill` command +* 0b25141 web: Add ENABLE_HSTS flag to disable strict-transport-security header +* f856037 web: add more config options +* eedac14 web: add ability to disable IPv6 +* af6f3ac doc: update CHANGELOG +* e3bb5c1 misc: working on latest + +## stable-5142-3 + +**Important:** This release should fix some update problems users found in -1 and -2 versions. The main problem observed is the introduction of XMPP WebSockets, which requires extra configuration for the /xmpp-wesocket route if a reverse proxy is used in front of this setup. Pure docker-compose installations don't need any changes. + +Based on stable release 5142-3. + +* c2c6460 prosody: fix cross-domain WS default value +* 8261f72 jicofo,jigase: add ability to extend the config file +* 6a4887d web: use env variables to set worker processes and connections +* 5679578 prosody: add env var to config cross domain settings +* effb30b prosody: always rebuild configs on start +* 905d431 jicofo,jigasi: always rebuild configs on start +* c52b64a misc: working on latest + +## stable-5142-2 + +Based on stable release 5142-2. + +* 700c04a web: properly handle acme.sh return codes +* 4cb181c web: install acme certs to persistent storage +* 1d2c68a web: fix running acme.sh on the right home directory +* 5c44a84 misc: stop using apt-key, it's deprecated +* 5f06c3a doc: update CHANGELOG +* 0f780b4 misc: working on latest + +## stable-5142-1 + +**Important:** This release includes 2 major changes: migrating the base image to Debian Buster and replacing certbot with acme.sh for getting Letś Encrypt certificates. Please report any problems you find! + +Based on stable release 5142-1. + +* b0cb4a1 web: update TLS config to Mozilla security guidelines +* 0601212 web: replace certbot with acme.sh +* 43f678d build: refactor Makefile +* b00f92a web: use Python 3 only for certbot +* 880b9b0 core: update base image to Debian Buster +* ba01190 web: prevent s6 from restarting cron if it shouldn't be run +* 42a4346 etherpad: use official image and making skin full width +* c36c4d0 web: always rebuild nginx configs on start +* aea4411 Adds private server. +* 6b69576 web: add ability to configure tokenAuthUrl +* ff6d9bc Fix websocket +* e5746ae misc: add ENABLE_PREJOIN_PAGE to .env +* 465816b web,prosody: turn on XMPP WebSocket by default +* d747bfb web,prosody: add XMPP WebSocket / Stream Management support +* 130eb55 jvb: migrate to new config file +* 5290499 doc: updated link for running behind NAT +* 7cb470c misc: support/encourage usage of ShellCheck +* 04a210f misc: working on latest + +## stable-5142 + +Based on stable release 5142. + +* 7ab45bb web: add ability to configure prejoin page +* 0c95794 jvb: regenerate config on every boot +* 3ef2221 jvb: add ability to set the WS domain with an env var +* 79d2601 jvb: add ability to specify set the WS_SERVER_ID with an env var +* b277926 jvb: make colibri websocket endpoints dynamic for multiple jvbs +* 991f695 web: remove no longer needed settings +* 8b7cbc3 revert "jicofo: no auth URL in JWT auth mode" +* 33b386b jvb: add missing variable to docker-compose +* 087f024 web: configure brandingDataUrl with env variables +* a404653 web: configure startAudioOnly using environment variable +* e195cbf jvb: make jvb apis available from outside the container +* 409cade web: configure Matomo using environment variables +* b731c60 doc: update CHANGELOG +* 0fbf3b7 misc: working on latest + +## stable-5076 + +**Important:** Starting with this release config.js is autogenerated with every container boot. +In addition, bridge channels now using WebSocket. Some setups may break on upgrade. + +Based on stable release 5076. + +* 5ceaf5f web: add IPv6 support +* aff3775 xmpp: allow recorders to bypass lobby +* ad5625b jvb: switch to WebSocket based bridge channels +* 8110336 web: add ability to configure the nginx resolver +* 2f47518 jicofo: no auth URL in JWT auth mode +* c149463 web: build config.js on each boot +* c792bbc base: update frep +* bec928c prosody: configure lobby on the guest domain is necessary +* bcbd977 jicofo: pass XMPP_MUC_DOMAIN through docker-compose.yml +* 8f9caa4 jicofo: set XMPP_MUC_COMPONENT_PREFIX +* 2a0120d web: set security headers also for non HTTPS +* e6586f2 jvb: set LOCAL_ADDRESS to the correct local IP (#630) +* 97f5e75 base: optimize size +* b78c89e misc: minor Dockerfile Improvements +* a754519 misc: working on latest + +## stable-4857 + +Based on stable release 4857. + +* a81ad73 prosody: add support for lobby +* baed605 web: fix removing closed captions button if transcription is enabled +* edecacd etherpad: add ability to use a external server +* a7563d4 jvb: use JVB_TCP_PORT for exposing the port +* b235ea1 prosody: disable s2s module +* 1d428a8 prosody: use a 2-stage build +* 613c26c misc: working on latest +* 4d72ee3 release: stable-4627-1 +* 22b7063 examples: update Traefik v1 example +* 1381b08 prosody: fix installing dependdencies +* 2900c11 misc: add extra line to tag message +* c57a84b misc: working on latest + +## stable-4627-1 + +Based on stable release 4627-1. + +* 1381b08 prosody: fix installing dependdencies +* 2900c11 misc: add extra line to tag message +* c57a84b misc: working on latest + +## stable-4627 + +Based on stable release 4627. + +* fdf5030 prosody: update configuration +* afafe23 prosody: shrink container size +* 8e7ea34 base: fix setting timezone +* 58441ae doc: update README +* 3c12526 etherpad: update to version 1.8.4 +* 0038e71 jibri: install extra dependency +* 0615ed6 doc: add missing volumes to quick start +* 2781865 doc: clarify usage of gen-passwords.sh +* a8d0b6c build: add PHONY target for "release" +* d4a35a6 misc: working on latest + +## stable-4548-1 + +Based on stable release 4548-1. + +* abf2f73 jicofo: fix setting incorrect auth URL scheme for JWT +* 3472ab0 jicofo: add ability to configure health checks +* ec3622b jibri: install jitsi-upload-integrations by default +* 0e7bc91 etherpad: pin image version +* 4fa50b9 jwt: do not load token_verification module with disabled authentication +* b0d76a2 jibri: add jq dep for upload integrations +* 53b58fd jvb: add jq, curl deps for graceful_shutdown.sh +* 2d063ad doc: update installation instructions +* e73df5f misc: working on latest + +## stable-4548 + +Based on stable release 4548. + +* a79fc0c misc: add release script +* 0f0adc8 compose: add image tag to compose files +* 0177765 misc: fix config volumes to work with SELinux +* eae3f5c jibri: chrome/driver 78 as a stopgap +* 78df6a4 doc: delete unnecessary dot +* 4426ed8 jibri: fix case when /dev/snd is not bound (https://github.com/jitsi/docker-jitsi-meet/issues/240#issuecomment-610422404) +* 125775a web: fix WASM MIME type +* e70975e web: enable GZIP compression for more file types +* 774aba5 misc: set ddefault timezone to UTC +* 3c3fc19 prosody: enable speaker stats and conferene duration modules +* f911df2 jvb: set JVB_TCP_MAPPED_PORT default value +* 1205170 jvb: allow `TCP_HARVESTER_MAPPED_PORT` to be configured +* f7796a1 prosody: add volume /prosody-plugins-custom to docker-compose +* d44230e prosody: use hashed xmpp auth + +## stable-4416 + +Based on stable release 4416. + +* b039b29 web: use certbot-auto +* b95c95d web: improve nginx configuration +* 2dd6b99 k8s: specify namespace for secret +* 7aa2d81 ldap: avoid unnecessary copy +* e1b47db exampless: update Traefik v2 example with UDP +* 0940605 doc: fix typos and minor grammar issues in README +* 1c4b11c doc: correct minor mistake +* c06867b doc: added steps for updating kernel manually in AWS installation +* dc46215 web: remove DHE suites support +* 367621f prosody: remove no longer needed patch +* 34e6601 doc: clarify acronym +* 2c95ab7 web: revert using PUBLIC_URL for BOSH URL +* 7fd7e2b Add docker-compose.override.yml to .gitignore (#438) +* 67a941b misc: update gen-passwords.sh shell code +* 4e2cec6 misc: add configurable service restart policy +* 729f9d2 doc: fix typo in env.example + +## stable-4384(-1) + +**Important security note:** Previous releases included default passwords for +system accounts, and users who didn't change them are at risk of getting +the authentication system circumvented by an attacker using a system account +with the default password. Please update and use the provided script +(instructions on the README) to generate a strong password for each system +account. + +Thanks joernchen for the security report. + +
+ +Based on stable release 4384. + +* 768b6c4 security: fail to start if using the old default password +* 1ffd472 security: add script to generate strong passwords +* a015710 security: don't provide default passwords +* aaec22d jigasi: fix typo in config +* ebfa142 docs: fix grammar and typos +* bab77e0 doc: update env.example +* 7652807 examples: traefik v2 +* 10983b4 prosody: prevent item-not-found error in certain cases +* 3524a52 base: fail to start the container if the init script fails +* 7c0c795 jicofo: only configure Jigasi brewery if Jigasi is configured +* 40c2920 build: add prepare command +* 93ba770 prosody: fix installing prosody from the right repository +* 3c07d76 doc: improve wording of README +* ed410d9 doc: fix typo +* fabfb2a doc: fix typo +* 5e6face web: use PUBLIC_URL for etherpaad base and BOSH URLs +* 264df04 jvb: switch to using Jitsi's STUN server by default +* 655cf6b web,prosody,jvb: prepare for new stable release +* ebb4536 doc: update CHANGELOG +* 06c3a83 doc: fix references to running behind NAT in the README + +## stable-4101-2 + +Based on stable release 4101. + +* b15bb28 prosody: update to latest stable version +* 75cb31b doc: add build instructions to README +* 25dbde9 doc: fix typo +* badc2d4 doc: add examples/README +* f6f6ca6 Merge branch 'dev' +* 52a1449 doc: clarify DOCKER_HOST_ADDRESS +* f26c9e6 prosody: fix ldap config template +* cd4a071 web: check for certbot's success and exit in case of a failure +* dea8d6c doc: fix typo +* 573c6fa doc: update diagrams +* 29125fd examples: add minimal example to run jitsi behind traefik + +## stable-4101-1 + +Based on stable release 4101. + +* b0def9a prosody: use epoll backend +* 8fa9f94 web: update nginx config from upstream +* 2f17380 doc: clarify account registration command +* edfd8f2 ldap: actually fix anonymous binds (Fixes #234) +* f4ac7cc misc: remove bogus quotation marks +* 0a68be1 jibri: start once jicofo has started +* 76acc65 doc: add tip re. ports to open on firewall to README +* e92a00c ldap: fix anonymous binds +* df40447 ldap: add option for ldap starttls support +* 1ebc535 doc: make localhost link in README clickable +* 33abdf3 doc: add mkdir -p ~/.jitsi-meet-cfg/... to README +* 2c93dce doc: fix typo in README +* d7bb2e6 doc: clarify HTTP vs HTTPS in README +* a1df1e0 Revert "prosody: fix restart loop on rolling deployment" +* 986071b jigasi: add missing transcription volumes to dockerfile +* 01eca74 jigasi: generate google cloud credentials from env vars +* cc2c042 prosody: fix restart loop on rolling deployment +* 5423a8a examples: adding simple kubernetes example +* 6eebabd jicofo: set owner jicofo rights for /config directory +* 69ba9ff jigasi: Updates jigasi client default options. +* 2b9a13b jicofo: add support of reservation REST API +* 8bfe7fb jicofo: add support of reservation REST API +* 9b17c05 web: fix letsencrypt renewal +* 6234a18 web: fix letsencrypt renewal diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0da277d --- /dev/null +++ b/LICENSE @@ -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. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3f55e25 --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +FORCE_REBUILD ?= 0 +JITSI_RELEASE ?= stable +JITSI_BUILD ?= latest +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: tag-all push-all + +build: + docker build $(BUILD_ARGS) --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):latest $(JITSI_REPO)/$(JITSI_SERVICE):$(JITSI_BUILD) + +push: + docker push $(JITSI_REPO)/$(JITSI_SERVICE):latest + 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: + docker pull debian:buster-slim + FORCE_REBUILD=1 $(MAKE) + +.PHONY: all build tag push clean prepare release $(addprefix build_,$(JITSI_SERVICES)) diff --git a/README.md b/README.md new file mode 100644 index 0000000..7c07d2c --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# 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/). + +## Installation + +The installation manual is available [here](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker). + +## TODO + +* Support container replicas (where applicable). +* TURN server. + diff --git a/base-java/Dockerfile b/base-java/Dockerfile new file mode 100644 index 0000000..7eec51a --- /dev/null +++ b/base-java/Dockerfile @@ -0,0 +1,12 @@ +ARG JITSI_REPO=jitsi +FROM ${JITSI_REPO}/base + +ENV JAVA_SYS_PROPS "-Djava.util.prefs.userRoot=/root" + +RUN \ + mkdir -p /usr/share/man/man1 && \ + wget -q https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public -O /etc/apt/trusted.gpg.d/openjdk.asc && \ + echo "deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main" > /etc/apt/sources.list.d/openjdk.list && \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y adoptopenjdk-8-hotspot-jre && \ + apt-cleanup diff --git a/base/Dockerfile b/base/Dockerfile new file mode 100644 index 0000000..a05e6dc --- /dev/null +++ b/base/Dockerfile @@ -0,0 +1,27 @@ +FROM debian:buster-slim + +ARG JITSI_RELEASE=stable +ARG FREP_VERSION=1.3.11 + +ENV S6_READ_ONLY_ROOT 1 +ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2 + +COPY rootfs / + +RUN \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y apt-transport-https apt-utils ca-certificates gnupg wget && \ + wget -qO - https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz | tar xfz - -C / && \ + wget -qO - https://download.jitsi.org/jitsi-key.gpg.key -O /etc/apt/trusted.gpg.d/jitsi.asc && \ + wget -q https://github.com/subchen/frep/releases/download/v$FREP_VERSION/frep-$FREP_VERSION-linux-amd64 -O /usr/bin/frep && \ + echo "deb https://download.jitsi.org $JITSI_RELEASE/" > /etc/apt/sources.list.d/jitsi.list && \ + echo "deb http://ftp.debian.org/debian buster-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/frep && \ + /install-devtools.sh + +RUN mkdir /config + +ENTRYPOINT [ "/pre-init.sh" ] diff --git a/base/rootfs/etc/apt/apt.conf.d/99local b/base/rootfs/etc/apt/apt.conf.d/99local new file mode 100644 index 0000000..a2fba33 --- /dev/null +++ b/base/rootfs/etc/apt/apt.conf.d/99local @@ -0,0 +1,2 @@ +APT::Install-Recommends "false"; +APT::Install-Suggests "false"; diff --git a/base/rootfs/etc/cont-finish.d/.gitkeep b/base/rootfs/etc/cont-finish.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/base/rootfs/etc/cont-init.d/.gitkeep b/base/rootfs/etc/cont-init.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/base/rootfs/etc/cont-init.d/01-set-timezone b/base/rootfs/etc/cont-init.d/01-set-timezone new file mode 100755 index 0000000..71e6dec --- /dev/null +++ b/base/rootfs/etc/cont-init.d/01-set-timezone @@ -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 diff --git a/base/rootfs/etc/fix-attrs.d/.gitkeep b/base/rootfs/etc/fix-attrs.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/base/rootfs/etc/services.d/.gitkeep b/base/rootfs/etc/services.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/base/rootfs/fix-permissions.sh b/base/rootfs/fix-permissions.sh new file mode 100755 index 0000000..3a59383 --- /dev/null +++ b/base/rootfs/fix-permissions.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +chown 1001:0 -R /config /var/log /var/lib /etc/jitsi +chmod g=u -R /config /var/log /var/lib /etc/localtime /etc/timezone /etc/s6 /etc/jitsi /etc/passwd /run /root /usr/bin + +# File should delete itself +rm -- "$0" diff --git a/base/rootfs/install-devtools.sh b/base/rootfs/install-devtools.sh new file mode 100755 index 0000000..2401a49 --- /dev/null +++ b/base/rootfs/install-devtools.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ "$JITSI_RELEASE" == "unstable" ]]; then + apt-dpkg-wrap apt-get update; + apt-dpkg-wrap apt-get install -y jq procps curl vim iputils-ping net-tools; + apt-cleanup; +fi + +# File should delete itself +rm -- "$0" diff --git a/base/rootfs/pre-init.sh b/base/rootfs/pre-init.sh new file mode 100755 index 0000000..02ca97c --- /dev/null +++ b/base/rootfs/pre-init.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +# set user for s6 +sed -i "s/\${3}/$(id -u)/g" /usr/bin/fix-attrs + +# workaround around mounts taking too much time +while ! mkdir -p /run/s6; do sleep 1; done + +# set username +if ! whoami > /dev/null 2>&1; then + if [ -w /etc/passwd ]; then + echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd + fi +fi + +exec /init diff --git a/base/rootfs/usr/bin/apt-cleanup b/base/rootfs/usr/bin/apt-cleanup new file mode 100755 index 0000000..1d3d61b --- /dev/null +++ b/base/rootfs/usr/bin/apt-cleanup @@ -0,0 +1,3 @@ +#!/bin/sh + +rm -rf /var/lib/apt/lists/ diff --git a/base/rootfs/usr/bin/apt-dpkg-wrap b/base/rootfs/usr/bin/apt-dpkg-wrap new file mode 100755 index 0000000..84ab0e2 --- /dev/null +++ b/base/rootfs/usr/bin/apt-dpkg-wrap @@ -0,0 +1,8 @@ +#!/bin/sh + +export LC_ALL=C +export DEBIAN_FRONTEND=noninteractive + +bin=$1 +shift +exec "$bin" "$@" diff --git a/base/rootfs/usr/bin/tpl b/base/rootfs/usr/bin/tpl new file mode 100755 index 0000000..c18fb0e --- /dev/null +++ b/base/rootfs/usr/bin/tpl @@ -0,0 +1,4 @@ +#!/bin/bash + +exec frep $1:- + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..00c4232 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,257 @@ +version: '3' + +services: + # Frontend + web: + image: jitsi/web:latest + restart: ${RESTART_POLICY} + ports: + - '${HTTP_PORT}:8080' + - '${HTTPS_PORT}:4443' + volumes: + - ${CONFIG}/web:/config:Z + - ${CONFIG}/transcripts:/usr/share/jitsi-meet/transcripts:Z + environment: + - ENABLE_LETSENCRYPT + - ENABLE_HTTP_REDIRECT + - ENABLE_HSTS + - ENABLE_XMPP_WEBSOCKET + - DISABLE_HTTPS + - LETSENCRYPT_DOMAIN + - LETSENCRYPT_EMAIL + - LETSENCRYPT_USE_STAGING + - PUBLIC_URL + - TZ + - AMPLITUDE_ID + - ANALYTICS_SCRIPT_URLS + - ANALYTICS_WHITELISTED_EVENTS + - BRIDGE_CHANNEL + - CALLSTATS_CUSTOM_SCRIPT_URL + - CALLSTATS_ID + - CALLSTATS_SECRET + - CHROME_EXTENSION_BANNER_JSON + - CONFCODE_URL + - CONFIG_EXTERNAL_CONNECT + - DEPLOYMENTINFO_ENVIRONMENT + - DEPLOYMENTINFO_ENVIRONMENT_TYPE + - DEPLOYMENTINFO_USERREGION + - DIALIN_NUMBERS_URL + - DIALOUT_AUTH_URL + - DIALOUT_CODES_URL + - DROPBOX_APPKEY + - DROPBOX_REDIRECT_URI + - DYNAMIC_BRANDING_URL + - ENABLE_AUDIO_PROCESSING + - ENABLE_AUTH + - ENABLE_CALENDAR + - ENABLE_FILE_RECORDING_SERVICE + - ENABLE_FILE_RECORDING_SERVICE_SHARING + - ENABLE_GUESTS + - ENABLE_IPV6 + - ENABLE_LIPSYNC + - ENABLE_NO_AUDIO_DETECTION + - ENABLE_P2P + - ENABLE_PREJOIN_PAGE + - ENABLE_WELCOME_PAGE + - ENABLE_CLOSE_PAGE + - ENABLE_RECORDING + - ENABLE_REMB + - ENABLE_REQUIRE_DISPLAY_NAME + - ENABLE_SIMULCAST + - ENABLE_STATS_ID + - ENABLE_STEREO + - ENABLE_SUBDOMAINS + - ENABLE_TALK_WHILE_MUTED + - ENABLE_TCC + - ENABLE_TRANSCRIPTIONS + - ETHERPAD_PUBLIC_URL + - ETHERPAD_URL_BASE + - GOOGLE_ANALYTICS_ID + - GOOGLE_API_APP_CLIENT_ID + - INVITE_SERVICE_URL + - JICOFO_AUTH_USER + - MATOMO_ENDPOINT + - MATOMO_SITE_ID + - MICROSOFT_API_APP_CLIENT_ID + - NGINX_RESOLVER + - NGINX_WORKER_PROCESSES + - NGINX_WORKER_CONNECTIONS + - PEOPLE_SEARCH_URL + - RESOLUTION + - RESOLUTION_MIN + - RESOLUTION_WIDTH + - RESOLUTION_WIDTH_MIN + - START_AUDIO_ONLY + - START_AUDIO_MUTED + - DISABLE_AUDIO_LEVELS + - ENABLE_NOISY_MIC_DETECTION + - START_BITRATE + - DESKTOP_SHARING_FRAMERATE_MIN + - DESKTOP_SHARING_FRAMERATE_MAX + - START_VIDEO_MUTED + - TESTING_CAP_SCREENSHARE_BITRATE + - TESTING_OCTO_PROBABILITY + - XMPP_AUTH_DOMAIN + - XMPP_BOSH_URL_BASE + - XMPP_DOMAIN + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_RECORDER_DOMAIN + - TOKEN_AUTH_URL + networks: + meet.jitsi: + aliases: + - ${XMPP_DOMAIN} + + # XMPP server + prosody: + image: jitsi/prosody:latest + restart: ${RESTART_POLICY} + expose: + - '5222' + - '5347' + - '5280' + volumes: + - ${CONFIG}/prosody/config:/config:Z + - ${CONFIG}/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z + environment: + - AUTH_TYPE + - ENABLE_AUTH + - ENABLE_GUESTS + - ENABLE_LOBBY + - ENABLE_XMPP_WEBSOCKET + - GLOBAL_MODULES + - GLOBAL_CONFIG + - LDAP_URL + - LDAP_BASE + - LDAP_BINDDN + - LDAP_BINDPW + - LDAP_FILTER + - LDAP_AUTH_METHOD + - LDAP_VERSION + - LDAP_USE_TLS + - LDAP_TLS_CIPHERS + - LDAP_TLS_CHECK_PEER + - LDAP_TLS_CACERT_FILE + - LDAP_TLS_CACERT_DIR + - LDAP_START_TLS + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_MODULES + - XMPP_MUC_MODULES + - XMPP_INTERNAL_MUC_MODULES + - XMPP_RECORDER_DOMAIN + - XMPP_CROSS_DOMAIN + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JIGASI_XMPP_USER + - JIGASI_XMPP_PASSWORD + - JIBRI_XMPP_USER + - JIBRI_XMPP_PASSWORD + - JIBRI_RECORDER_USER + - JIBRI_RECORDER_PASSWORD + - JWT_APP_ID + - JWT_APP_SECRET + - JWT_ACCEPTED_ISSUERS + - JWT_ACCEPTED_AUDIENCES + - JWT_ASAP_KEYSERVER + - JWT_ALLOW_EMPTY + - JWT_AUTH_TYPE + - JWT_TOKEN_AUTH_MODULE + - LOG_LEVEL + - PUBLIC_URL + - TZ + networks: + meet.jitsi: + aliases: + - ${XMPP_SERVER} + + # Focus component + jicofo: + image: jitsi/jicofo:latest + restart: ${RESTART_POLICY} + volumes: + - ${CONFIG}/jicofo:/config:Z + environment: + - AUTH_TYPE + - BRIDGE_AVG_PARTICIPANT_STRESS + - BRIDGE_STRESS_THRESHOLD + - ENABLE_AUTH + - ENABLE_AUTO_OWNER + - ENABLE_CODEC_VP8 + - ENABLE_CODEC_VP9 + - ENABLE_CODEC_H264 + - ENABLE_RECORDING + - ENABLE_SCTP + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS + - JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT + - JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT + - JICOFO_ENABLE_HEALTH_CHECKS + - JICOFO_SHORT_ID + - JICOFO_RESERVATION_ENABLED + - JICOFO_RESERVATION_REST_BASE_URL + - JIBRI_BREWERY_MUC + - JIBRI_REQUEST_RETRIES + - JIBRI_PENDING_TIMEOUT + - JIGASI_BREWERY_MUC + - JIGASI_SIP_URI + - JVB_BREWERY_MUC + - MAX_BRIDGE_PARTICIPANTS + - OCTO_BRIDGE_SELECTION_STRATEGY + - TZ + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_SERVER + depends_on: + - prosody + networks: + meet.jitsi: + + # Video bridge + jvb: + image: jitsi/jvb:latest + restart: ${RESTART_POLICY} + ports: + - '${JVB_PORT}:${JVB_PORT}/udp' + - '${JVB_TCP_PORT}:${JVB_TCP_PORT}' + volumes: + - ${CONFIG}/jvb:/config:Z + environment: + - DOCKER_HOST_ADDRESS + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_SERVER + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JVB_BREWERY_MUC + - JVB_PORT + - JVB_TCP_HARVESTER_DISABLED + - JVB_TCP_PORT + - JVB_TCP_MAPPED_PORT + - JVB_STUN_SERVERS + - JVB_ENABLE_APIS + - JVB_WS_DOMAIN + - JVB_WS_SERVER_ID + - PUBLIC_URL + - TZ + depends_on: + - prosody + networks: + meet.jitsi: + aliases: + - jvb.meet.jitsi + +# Custom network so all services can communicate using a FQDN +networks: + meet.jitsi: diff --git a/env.example b/env.example new file mode 100644 index 0000000..a95a13d --- /dev/null +++ b/env.example @@ -0,0 +1,381 @@ +# shellcheck disable=SC2034 + +# 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 component password for Jicofo +JICOFO_COMPONENT_SECRET= + +# 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 recorder password for Jibri client connections +JIBRI_RECORDER_PASSWORD= + +# XMPP password for Jibri client connections +JIBRI_XMPP_PASSWORD= + + +# +# Basic configuration options +# + +# Directory where all configuration will be stored +CONFIG=~/.jitsi-meet-cfg + +# Exposed HTTP port +HTTP_PORT=8000 + +# Exposed HTTPS port +HTTPS_PORT=8443 + +# System time zone +TZ=UTC + +# Public URL for the web service (required) +#PUBLIC_URL=https://meet.example.com:8443 + +# IP address of the Docker host +# 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 +#DOCKER_HOST_ADDRESS=192.168.1.1 + +# Control whether the lobby feature should be enabled or not +#ENABLE_LOBBY=1 + +# Show a prejoin page before entering a conference +#ENABLE_PREJOIN_PAGE=0 + +# Enable the welcome page +#ENABLE_WELCOME_PAGE=1 + +# Enable the close page +#ENABLE_CLOSE_PAGE=0 + +# Disable measuring of audio levels +#DISABLE_AUDIO_LEVELS=0 + +# Enable noisy mic detection +#ENABLE_NOISY_MIC_DETECTION=1 + +# +# 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 + + +# +# Etherpad integration (for document sharing) +# + +# Set etherpad-lite URL in docker local network (uncomment to enable) +#ETHERPAD_URL_BASE=http://etherpad.meet.jitsi:9001 + +# Set etherpad-lite public URL (uncomment to enable) +#ETHERPAD_PUBLIC_URL=https://etherpad.my.domain + +# Name your etherpad instance! +ETHERPAD_TITLE=Video Chat + +# The default text of a pad +ETHERPAD_DEFAULT_PAD_TEXT=Welcome to Web Chat!\n\n + +# Name of the skin for etherpad +ETHERPAD_SKIN_NAME=colibris + +# Skin variants for etherpad +ETHERPAD_SKIN_VARIANTS=super-light-toolbar super-light-editor light-background full-width-editor + + +# +# 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 +#ENABLE_AUTH=1 + +# Enable guest access +#ENABLE_GUESTS=1 + +# Select authentication type: internal, jwt or ldap +#AUTH_TYPE=internal + +# JWT authentication +# + +# Application identifier +#JWT_APP_ID=my_jitsi_app_id + +# Application secret known only to your token +#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 + + +# +# Advanced configuration options (you generally don't need to change these) +# + +# Internal XMPP domain +XMPP_DOMAIN=meet.jitsi + +# Internal XMPP server +XMPP_SERVER=xmpp.meet.jitsi + +# Internal XMPP server URL +XMPP_BOSH_URL_BASE=http://xmpp.meet.jitsi:5280 + +# Internal XMPP domain for authenticated services +XMPP_AUTH_DOMAIN=auth.meet.jitsi + +# XMPP domain for the MUC +XMPP_MUC_DOMAIN=muc.meet.jitsi + +# XMPP domain for the internal MUC used for jibri, jigasi and jvb pools +XMPP_INTERNAL_MUC_DOMAIN=internal-muc.meet.jitsi + +# XMPP domain for unauthenticated users +XMPP_GUEST_DOMAIN=guest.meet.jitsi + +# Comma separated list of domains for cross domain policy or "true" to allow all +# The PUBLIC_URL is always allowed +#XMPP_CROSS_DOMAIN=true + +# Custom Prosody modules for XMPP_DOMAIN (comma separated) +XMPP_MODULES= + +# Custom Prosody modules for MUC component (comma separated) +XMPP_MUC_MODULES= + +# Custom Prosody modules for internal MUC component (comma separated) +XMPP_INTERNAL_MUC_MODULES= + +# MUC for the JVB pool +JVB_BREWERY_MUC=jvbbrewery + +# XMPP user for JVB client connections +JVB_AUTH_USER=jvb + +# STUN servers used to discover the server's public IP +JVB_STUN_SERVERS=meet-jit-si-turnrelay.jitsi.net:443 + +# Media port for the Jitsi Videobridge +JVB_PORT=10000 + +# TCP Fallback for Jitsi Videobridge for when UDP isn't available +JVB_TCP_HARVESTER_DISABLED=true +JVB_TCP_PORT=4443 +JVB_TCP_MAPPED_PORT=4443 + +# A comma separated list of APIs to enable when the JVB is started [default: none] +# See https://github.com/jitsi/jitsi-videobridge/blob/master/doc/rest.md for more information +#JVB_ENABLE_APIS=rest,colibri + +# XMPP user for Jicofo client connections. +# NOTE: this option doesn't currently work due to a bug +JICOFO_AUTH_USER=focus + +# Base URL of Jicofo's reservation REST API +#JICOFO_RESERVATION_REST_BASE_URL=http://reservation.example.com + +# Enable Jicofo's health check REST API (http://:8888/about/health) +#JICOFO_ENABLE_HEALTH_CHECKS=true + +# XMPP user for Jigasi MUC client connections +JIGASI_XMPP_USER=jigasi + +# MUC name for the Jigasi pool +JIGASI_BREWERY_MUC=jigasibrewery + +# Minimum port for media used by Jigasi +JIGASI_PORT_MIN=20000 + +# Maximum port for media used by Jigasi +JIGASI_PORT_MAX=20050 + +# Enable SDES srtp +#JIGASI_ENABLE_SDES_SRTP=1 + +# Keepalive method +#JIGASI_SIP_KEEP_ALIVE_METHOD=OPTIONS + +# Health-check extension +#JIGASI_HEALTH_CHECK_SIP_URI=keepalive + +# Health-check interval +#JIGASI_HEALTH_CHECK_INTERVAL=300000 +# +# Enable Jigasi transcription +#ENABLE_TRANSCRIPTIONS=1 + +# Jigasi will record audio when transcriber is on [default: false] +#JIGASI_TRANSCRIBER_RECORD_AUDIO=true + +# Jigasi will send transcribed text to the chat when transcriber is on [default: false] +#JIGASI_TRANSCRIBER_SEND_TXT=true + +# Jigasi will post an url to the chat with transcription file [default: false] +#JIGASI_TRANSCRIBER_ADVERTISE_URL=true + +# Credentials for connect to Cloud Google API from Jigasi +# Please read https://cloud.google.com/text-to-speech/docs/quickstart-protocol +# section "Before you begin" paragraph 1 to 5 +# Copy the values from the json to the related env vars +#GC_PROJECT_ID= +#GC_PRIVATE_KEY_ID= +#GC_PRIVATE_KEY= +#GC_CLIENT_EMAIL= +#GC_CLIENT_ID= +#GC_CLIENT_CERT_URL= + +# Enable recording +#ENABLE_RECORDING=1 + +# XMPP domain for the jibri recorder +XMPP_RECORDER_DOMAIN=recorder.meet.jitsi + +# XMPP recorder user for Jibri client connections +JIBRI_RECORDER_USER=recorder + +# Directory for recordings inside Jibri container +JIBRI_RECORDING_DIR=/config/recordings + +# The finalizing script. Will run after recording is complete +#JIBRI_FINALIZE_RECORDING_SCRIPT_PATH=/config/finalize.sh + +# XMPP user for Jibri client connections +JIBRI_XMPP_USER=jibri + +# MUC name for the Jibri pool +JIBRI_BREWERY_MUC=jibribrewery + +# MUC connection timeout +JIBRI_PENDING_TIMEOUT=90 + +# When jibri gets a request to start a service for a room, the room +# jid will look like: roomName@optional.prefixes.subdomain.xmpp_domain +# We'll build the url for the call by transforming that into: +# https://xmpp_domain/subdomain/roomName +# So if there are any prefixes in the jid (like jitsi meet, which +# has its participants join a muc at conference.xmpp_domain) then +# list that prefix here so it can be stripped out to generate +# the call url correctly +JIBRI_STRIP_DOMAIN_JID=muc + +# Directory for logs inside Jibri container +JIBRI_LOGS_DIR=/config/logs + +# Disable HTTPS: handle TLS connections outside of this setup +#DISABLE_HTTPS=1 + +# Redirect HTTP traffic to HTTPS +# Necessary for Let's Encrypt, relies on standard HTTPS port (443) +#ENABLE_HTTP_REDIRECT=1 + +# Send a `strict-transport-security` header to force browsers to use +# a secure and trusted connection. Recommended for production use. +# Defaults to 1 (send the header). +# ENABLE_HSTS=1 + +# Enable IPv6 +# Provides means to disable IPv6 in environments that don't support it (get with the times, people!) +#ENABLE_IPV6=1 + +# Container restart policy +# Defaults to unless-stopped +RESTART_POLICY=unless-stopped + +# Authenticate using external service or just focus external auth window if there is one already. +# TOKEN_AUTH_URL=https://auth.meet.example.com/{room} diff --git a/etherpad.yml b/etherpad.yml new file mode 100644 index 0000000..bab9378 --- /dev/null +++ b/etherpad.yml @@ -0,0 +1,16 @@ +version: '3' + +services: + # Etherpad: real-time collaborative document editing + etherpad: + image: etherpad/etherpad:1.8.6 + restart: ${RESTART_POLICY} + environment: + - TITLE=${ETHERPAD_TITLE} + - DEFAULT_PAD_TEXT=${ETHERPAD_DEFAULT_PAD_TEXT} + - SKIN_NAME=${ETHERPAD_SKIN_NAME} + - SKIN_VARIANTS=${ETHERPAD_SKIN_VARIANTS} + networks: + meet.jitsi: + aliases: + - etherpad.meet.jitsi diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..84ca610 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,11 @@ +# Community Examples + +The examples contained in this directory have been provided by the community +and allow users to run the container setup in scenarios other than the +default one (using Docker Compose). + +Since they are maintained by the community, they may not provide the same +features as the default setup. + +No support is provided for these, but if you found a bug and can fix it +we'll be happy to accept a Pull-Request to fix it! diff --git a/examples/kubernetes/README.md b/examples/kubernetes/README.md new file mode 100644 index 0000000..6d5c6e3 --- /dev/null +++ b/examples/kubernetes/README.md @@ -0,0 +1,26 @@ +# Install guide for kubernetes + +This guide will deploy jitsi in the most simple way: as several containers in a single pod. This is enough to start in case your hardware is enough. If you need to scale components to severa instance, you'll have to modify it to use several services and pods. + +Create a namespace to deploy jitsi to: + +`kubectl create namespace jitsi` + +Add the secret with secret values (replace `...` with some random strings): + +`kubectl create secret generic jitsi-config -n jitsi --from-literal=JICOFO_COMPONENT_SECRET=... --from-literal=JICOFO_AUTH_PASSWORD=... --from-literal=JVB_AUTH_PASSWORD=... ` + +Deploy the service to listen for JVB UDP traffic on all cluster nodes port 30300: + +`kubectl create -f jvb-service.yaml` + +Now we can deploy the rest of the application. First modify the `DOCKER_HOST_ADDRESS` env value in deployment.yaml to point to one of nodes in your cluster (or load-balancer for all nodes if you have one), and then deploy it: + +`kubectl create -f deployment.yaml` + +To expose the webapp, we can use Ingress (replace the `host` value with your actual hostname): + +`kubectl create -f web-service.yaml` + +You can either use "https" or "http" service port, depending on whether your ingress allows self-signed certs. + diff --git a/examples/kubernetes/deployment.yaml b/examples/kubernetes/deployment.yaml new file mode 100644 index 0000000..e246689 --- /dev/null +++ b/examples/kubernetes/deployment.yaml @@ -0,0 +1,145 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + k8s-app: jitsi + name: jitsi + namespace: jitsi +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + k8s-app: jitsi + template: + metadata: + labels: + k8s-app: jitsi + spec: + containers: + - name: jicofo + image: jitsi/jicofo + imagePullPolicy: Always + env: + - name: XMPP_SERVER + value: localhost + - name: XMPP_DOMAIN + value: meet.jitsi + - name: XMPP_AUTH_DOMAIN + value: auth.meet.jitsi + - name: XMPP_MUC_DOMAIN + value: muc.meet.jitsi + - name: XMPP_INTERNAL_MUC_DOMAIN + value: internal-muc.meet.jitsi + - name: JICOFO_COMPONENT_SECRET + valueFrom: + secretKeyRef: + name: jitsi-config + key: JICOFO_COMPONENT_SECRET + - name: JICOFO_AUTH_USER + value: focus + - name: JICOFO_AUTH_PASSWORD + valueFrom: + secretKeyRef: + name: jitsi-config + key: JICOFO_AUTH_PASSWORD + - name: TZ + value: America/Los_Angeles + - name: JVB_BREWERY_MUC + value: jvbbrewery + - name: prosody + image: jitsi/prosody + imagePullPolicy: Always + env: + - name: XMPP_DOMAIN + value: meet.jitsi + - name: XMPP_AUTH_DOMAIN + value: auth.meet.jitsi + - name: XMPP_MUC_DOMAIN + value: muc.meet.jitsi + - name: XMPP_INTERNAL_MUC_DOMAIN + value: internal-muc.meet.jitsi + - name: JICOFO_COMPONENT_SECRET + valueFrom: + secretKeyRef: + name: jitsi-config + key: JICOFO_COMPONENT_SECRET + - name: JVB_AUTH_USER + value: jvb + - name: JVB_AUTH_PASSWORD + valueFrom: + secretKeyRef: + name: jitsi-config + key: JVB_AUTH_PASSWORD + - name: JICOFO_AUTH_USER + value: focus + - name: JICOFO_AUTH_PASSWORD + valueFrom: + secretKeyRef: + name: jitsi-config + key: JICOFO_AUTH_PASSWORD + - name: TZ + value: America/Los_Angeles + - name: JVB_TCP_HARVESTER_DISABLED + value: "true" + - name: web + image: jitsi/web + imagePullPolicy: Always + env: + - name: XMPP_SERVER + value: localhost + - name: JICOFO_AUTH_USER + value: focus + - name: XMPP_DOMAIN + value: meet.jitsi + - name: XMPP_AUTH_DOMAIN + value: auth.meet.jitsi + - name: XMPP_INTERNAL_MUC_DOMAIN + value: internal-muc.meet.jitsi + - name: XMPP_BOSH_URL_BASE + value: http://127.0.0.1:5280 + - name: XMPP_MUC_DOMAIN + value: muc.meet.jitsi + - name: TZ + value: America/Los_Angeles + - name: JVB_TCP_HARVESTER_DISABLED + value: "true" + - name: jvb + image: jitsi/jvb + imagePullPolicy: Always + env: + - name: XMPP_SERVER + value: localhost + - name: DOCKER_HOST_ADDRESS + value: + - name: XMPP_DOMAIN + value: meet.jitsi + - name: XMPP_AUTH_DOMAIN + value: auth.meet.jitsi + - name: XMPP_INTERNAL_MUC_DOMAIN + value: internal-muc.meet.jitsi + - name: JVB_STUN_SERVERS + value: stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302 + - name: JICOFO_AUTH_USER + value: focus + - name: JVB_TCP_HARVESTER_DISABLED + value: "true" + - name: JVB_AUTH_USER + value: jvb + - name: JVB_PORT + value: "30300" + - name: JVB_AUTH_PASSWORD + valueFrom: + secretKeyRef: + name: jitsi-config + key: JVB_AUTH_PASSWORD + - name: JICOFO_AUTH_PASSWORD + valueFrom: + secretKeyRef: + name: jitsi-config + key: JICOFO_AUTH_PASSWORD + - name: JVB_BREWERY_MUC + value: jvbbrewery + - name: TZ + value: America/Los_Angeles diff --git a/examples/kubernetes/jvb-service.yaml b/examples/kubernetes/jvb-service.yaml new file mode 100644 index 0000000..6cf1434 --- /dev/null +++ b/examples/kubernetes/jvb-service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + service: jvb + name: jvb-udp + namespace: jitsi +spec: + type: NodePort + externalTrafficPolicy: Cluster + ports: + - port: 30300 + protocol: UDP + targetPort: 30300 + nodePort: 30300 + selector: + k8s-app: jitsi diff --git a/examples/kubernetes/web-service.yaml b/examples/kubernetes/web-service.yaml new file mode 100644 index 0000000..00362fd --- /dev/null +++ b/examples/kubernetes/web-service.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + service: web + name: web + namespace: jitsi +spec: + ports: + - name: "http" + port: 8080 + targetPort: 8080 + - name: "https" + port: 4443 + targetPort: 4443 + selector: + k8s-app: jitsi +--- + apiVersion: networking.k8s.io/v1beta1 + kind: Ingress + metadata: + name: jitsi + namespace: jitsi + spec: + rules: + - host: ... + http: + paths: + - path: / + backend: + serviceName: web + servicePort: https \ No newline at end of file diff --git a/examples/traefik-v2/README.md b/examples/traefik-v2/README.md new file mode 100644 index 0000000..585f224 --- /dev/null +++ b/examples/traefik-v2/README.md @@ -0,0 +1,18 @@ +# Basic configuration to use with the traefik reverse proxy + +Note: Tested with traefik 2.2.0 + +- When running behind traefik, it's a better practice to remove the port-binds for the web service. +- The provided example uses an external network with the name "web". This is the network which moste likely was created while setting up traefik. +- Look for comments starting with **#traefik:** to see the changes made in docker-compose.yml. +- Traefik obtains Let's Encrypt certificates automatically. + +Uncomment and set DOCKER_HOST_ADDRESS in .env. I'm pretty sure, that this is mandatory for the docker-setup and should be clearer in the original README. Could be the proxying, didn't investigate further. + +## TODO + +Add or rewrite the example with docker-compose extends + +````env +DOCKER_HOST_ADDRESS=1.2.3.4 +```` diff --git a/examples/traefik-v2/docker-compose.yml b/examples/traefik-v2/docker-compose.yml new file mode 100644 index 0000000..f4bc173 --- /dev/null +++ b/examples/traefik-v2/docker-compose.yml @@ -0,0 +1,269 @@ +version: '3' + +services: + # Frontend + web: + image: jitsi/web + volumes: + - ${CONFIG}/web:/config + - ${CONFIG}/web/letsencrypt:/etc/letsencrypt + - ${CONFIG}/transcripts:/usr/share/jitsi-meet/transcripts + environment: + - ENABLE_LETSENCRYPT + - ENABLE_HTTP_REDIRECT + - ENABLE_HSTS + - ENABLE_XMPP_WEBSOCKET + - DISABLE_HTTPS + - LETSENCRYPT_DOMAIN + - LETSENCRYPT_EMAIL + - LETSENCRYPT_USE_STAGING + - PUBLIC_URL + - TZ + - AMPLITUDE_ID + - ANALYTICS_SCRIPT_URLS + - ANALYTICS_WHITELISTED_EVENTS + - BRIDGE_CHANNEL + - CALLSTATS_CUSTOM_SCRIPT_URL + - CALLSTATS_ID + - CALLSTATS_SECRET + - CHROME_EXTENSION_BANNER_JSON + - CONFCODE_URL + - CONFIG_EXTERNAL_CONNECT + - DEPLOYMENTINFO_ENVIRONMENT + - DEPLOYMENTINFO_ENVIRONMENT_TYPE + - DEPLOYMENTINFO_USERREGION + - DIALIN_NUMBERS_URL + - DIALOUT_AUTH_URL + - DIALOUT_CODES_URL + - DROPBOX_APPKEY + - DROPBOX_REDIRECT_URI + - DYNAMIC_BRANDING_URL + - ENABLE_AUDIO_PROCESSING + - ENABLE_AUTH + - ENABLE_CALENDAR + - ENABLE_FILE_RECORDING_SERVICE + - ENABLE_FILE_RECORDING_SERVICE_SHARING + - ENABLE_GUESTS + - ENABLE_IPV6 + - ENABLE_LIPSYNC + - ENABLE_NO_AUDIO_DETECTION + - ENABLE_P2P + - ENABLE_PREJOIN_PAGE + - ENABLE_WELCOME_PAGE + - ENABLE_CLOSE_PAGE + - ENABLE_RECORDING + - ENABLE_REMB + - ENABLE_REQUIRE_DISPLAY_NAME + - ENABLE_SIMULCAST + - ENABLE_STATS_ID + - ENABLE_STEREO + - ENABLE_SUBDOMAINS + - ENABLE_TALK_WHILE_MUTED + - ENABLE_TCC + - ENABLE_TRANSCRIPTIONS + - ETHERPAD_PUBLIC_URL + - ETHERPAD_URL_BASE + - GOOGLE_ANALYTICS_ID + - GOOGLE_API_APP_CLIENT_ID + - INVITE_SERVICE_URL + - JICOFO_AUTH_USER + - MATOMO_ENDPOINT + - MATOMO_SITE_ID + - MICROSOFT_API_APP_CLIENT_ID + - NGINX_RESOLVER + - NGINX_WORKER_PROCESSES + - NGINX_WORKER_CONNECTIONS + - PEOPLE_SEARCH_URL + - RESOLUTION + - RESOLUTION_MIN + - RESOLUTION_WIDTH + - RESOLUTION_WIDTH_MIN + - START_AUDIO_ONLY + - START_AUDIO_MUTED + - DISABLE_AUDIO_LEVELS + - ENABLE_NOISY_MIC_DETECTION + - START_BITRATE + - DESKTOP_SHARING_FRAMERATE_MIN + - DESKTOP_SHARING_FRAMERATE_MAX + - START_VIDEO_MUTED + - TESTING_CAP_SCREENSHARE_BITRATE + - TESTING_OCTO_PROBABILITY + - XMPP_AUTH_DOMAIN + - XMPP_BOSH_URL_BASE + - XMPP_DOMAIN + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_RECORDER_DOMAIN + - TOKEN_AUTH_URL + networks: + # traefik: change the following line to your external docker network + web: + meet.jitsi: + aliases: + - ${XMPP_DOMAIN} + labels: + traefik.http.middlewares.redirect.redirectscheme.scheme: https + traefik.http.routers.app-http.entrypoints: web + traefik.http.routers.app-http.middlewares: redirect + traefik.http.routers.app-http.rule: 'Host(`your.host.name`)' + traefik.http.routers.app.entrypoints: websecure + traefik.http.routers.app.rule: 'Host(`your.host.name`)' + traefik.http.routers.app.tls: 'true' + traefik.http.routers.app.tls.certresolver: le + traefik.http.services.app.loadbalancer.server.port: 80 + # traefik: change the following line to your external docker network + traefik.docker.network: web + + # XMPP server + prosody: + image: jitsi/prosody + expose: + - '5222' + - '5347' + - '5280' + volumes: + - ${CONFIG}/prosody:/config + environment: + - AUTH_TYPE + - ENABLE_AUTH + - ENABLE_GUESTS + - ENABLE_LOBBY + - ENABLE_XMPP_WEBSOCKET + - GLOBAL_MODULES + - GLOBAL_CONFIG + - LDAP_URL + - LDAP_BASE + - LDAP_BINDDN + - LDAP_BINDPW + - LDAP_FILTER + - LDAP_AUTH_METHOD + - LDAP_VERSION + - LDAP_USE_TLS + - LDAP_TLS_CIPHERS + - LDAP_TLS_CHECK_PEER + - LDAP_TLS_CACERT_FILE + - LDAP_TLS_CACERT_DIR + - LDAP_START_TLS + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_MODULES + - XMPP_MUC_MODULES + - XMPP_INTERNAL_MUC_MODULES + - XMPP_RECORDER_DOMAIN + - XMPP_CROSS_DOMAIN + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JIGASI_XMPP_USER + - JIGASI_XMPP_PASSWORD + - JIBRI_XMPP_USER + - JIBRI_XMPP_PASSWORD + - JIBRI_RECORDER_USER + - JIBRI_RECORDER_PASSWORD + - JWT_APP_ID + - JWT_APP_SECRET + - JWT_ACCEPTED_ISSUERS + - JWT_ACCEPTED_AUDIENCES + - JWT_ASAP_KEYSERVER + - JWT_ALLOW_EMPTY + - JWT_AUTH_TYPE + - JWT_TOKEN_AUTH_MODULE + - LOG_LEVEL + - PUBLIC_URL + - TZ + networks: + meet.jitsi: + aliases: + - ${XMPP_SERVER} + + # Focus component + jicofo: + image: jitsi/jicofo + volumes: + - ${CONFIG}/jicofo:/config + environment: + - AUTH_TYPE + - BRIDGE_AVG_PARTICIPANT_STRESS + - BRIDGE_STRESS_THRESHOLD + - ENABLE_AUTH + - ENABLE_AUTO_OWNER + - ENABLE_CODEC_VP8 + - ENABLE_CODEC_VP9 + - ENABLE_CODEC_H264 + - ENABLE_RECORDING + - ENABLE_SCTP + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS + - JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT + - JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT + - JICOFO_ENABLE_HEALTH_CHECKS + - JICOFO_SHORT_ID + - JICOFO_RESERVATION_ENABLED + - JICOFO_RESERVATION_REST_BASE_URL + - JIBRI_BREWERY_MUC + - JIBRI_REQUEST_RETRIES + - JIBRI_PENDING_TIMEOUT + - JIGASI_BREWERY_MUC + - JIGASI_SIP_URI + - JVB_BREWERY_MUC + - MAX_BRIDGE_PARTICIPANTS + - OCTO_BRIDGE_SELECTION_STRATEGY + - TZ + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_SERVER + depends_on: + - prosody + networks: + meet.jitsi: + + # Video bridge + jvb: + image: jitsi/jvb + ports: + - '${JVB_PORT}:${JVB_PORT}/udp' + - '${JVB_TCP_MAPPED_PORT}:${JVB_TCP_PORT}' + volumes: + - ${CONFIG}/jvb:/config + environment: + - DOCKER_HOST_ADDRESS + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_SERVER + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JVB_BREWERY_MUC + - JVB_PORT + - JVB_TCP_HARVESTER_DISABLED + - JVB_TCP_PORT + - JVB_TCP_MAPPED_PORT + - JVB_STUN_SERVERS + - JVB_ENABLE_APIS + - JVB_WS_DOMAIN + - JVB_WS_SERVER_ID + - PUBLIC_URL + - TZ + depends_on: + - prosody + networks: + meet.jitsi: + labels: + traefik.udp.routers.jvb.entrypoints: video + traefik.udp.routers.jvb.service: jvb + traefik.udp.services.jvb.loadbalancer.server.port: 10000 + +# Custom network so all services can communicate using a FQDN +networks: + meet.jitsi: + # traefik: change the following line to your external docker network + web: + external: true diff --git a/examples/traefik/README.md b/examples/traefik/README.md new file mode 100644 index 0000000..b2c4ce0 --- /dev/null +++ b/examples/traefik/README.md @@ -0,0 +1,17 @@ +# Basic configuration to use with the traefik reverse proxy + +Note: Tested with traefik 1.7 + +- When running behind traefik, it's a better practice to remove the port-binds for the web service. +- The provided example uses an external network with the name "web". This is the network which moste likely was created while setting up traefik. +- Look for comments starting with **#traefik:** to see the changes made in docker-compose.yml. + +Uncomment and set DOCKER_HOST_ADDRESS in .env. I'm pretty sure, that this is mandatory for the docker-setup and should be clearer in the original README. Could be the proxying, didn't investigate further. + +## TODO + +Add or rewrite the example with docker-compose extends + +````env +DOCKER_HOST_ADDRESS=1.2.3.4 +```` diff --git a/examples/traefik/docker-compose.yml b/examples/traefik/docker-compose.yml new file mode 100644 index 0000000..7114cd4 --- /dev/null +++ b/examples/traefik/docker-compose.yml @@ -0,0 +1,180 @@ +version: '3' + +services: + # Frontend + web: + image: jitsi/web + restart: ${RESTART_POLICY} + volumes: + - ${CONFIG}/web:/config:Z + - ${CONFIG}/web/letsencrypt:/etc/letsencrypt:Z + - ${CONFIG}/transcripts:/usr/share/jitsi-meet/transcripts:Z + environment: + - ENABLE_AUTH + - ENABLE_GUESTS + - ENABLE_LETSENCRYPT + - ENABLE_HTTP_REDIRECT + - ENABLE_TRANSCRIPTIONS + - DISABLE_HTTPS + - JICOFO_AUTH_USER + - LETSENCRYPT_DOMAIN + - LETSENCRYPT_EMAIL + - PUBLIC_URL + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_BOSH_URL_BASE + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_RECORDER_DOMAIN + - ETHERPAD_URL_BASE + - ETHERPAD_PUBLIC_URL + - TZ + - JIBRI_BREWERY_MUC + - JIBRI_PENDING_TIMEOUT + - JIBRI_XMPP_USER + - JIBRI_XMPP_PASSWORD + - JIBRI_RECORDER_USER + - JIBRI_RECORDER_PASSWORD + - ENABLE_RECORDING + networks: + # traefik: change the following line to your external docker network + web: + meet.jitsi: + aliases: + - ${XMPP_DOMAIN} + labels: + # traefik: change that to your external network + - "traefik.docker.network=web" + - "traefik.enable=true" + - "traefik.backend=jc_backend" + # traefik: change that to your actual fqdn + - "traefik.basic.frontend.rule=Host:your.host.name" + - "traefik.basic.port=8080" + + # XMPP server + prosody: + image: jitsi/prosody + restart: ${RESTART_POLICY} + expose: + - '5222' + - '5347' + - '5280' + volumes: + - ${CONFIG}/prosody/config:/config:Z + - ${CONFIG}/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z + environment: + - AUTH_TYPE + - ENABLE_AUTH + - ENABLE_GUESTS + - GLOBAL_MODULES + - GLOBAL_CONFIG + - LDAP_URL + - LDAP_BASE + - LDAP_BINDDN + - LDAP_BINDPW + - LDAP_FILTER + - LDAP_AUTH_METHOD + - LDAP_VERSION + - LDAP_USE_TLS + - LDAP_TLS_CIPHERS + - LDAP_TLS_CHECK_PEER + - LDAP_TLS_CACERT_FILE + - LDAP_TLS_CACERT_DIR + - LDAP_START_TLS + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_GUEST_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_MODULES + - XMPP_MUC_MODULES + - XMPP_INTERNAL_MUC_MODULES + - XMPP_RECORDER_DOMAIN + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JIGASI_XMPP_USER + - JIGASI_XMPP_PASSWORD + - JIBRI_XMPP_USER + - JIBRI_XMPP_PASSWORD + - JIBRI_RECORDER_USER + - JIBRI_RECORDER_PASSWORD + - JWT_APP_ID + - JWT_APP_SECRET + - JWT_ACCEPTED_ISSUERS + - JWT_ACCEPTED_AUDIENCES + - JWT_ASAP_KEYSERVER + - JWT_ALLOW_EMPTY + - JWT_AUTH_TYPE + - JWT_TOKEN_AUTH_MODULE + - LOG_LEVEL + - TZ + networks: + meet.jitsi: + aliases: + - ${XMPP_SERVER} + + # Focus component + jicofo: + image: jitsi/jicofo + restart: ${RESTART_POLICY} + volumes: + - ${CONFIG}/jicofo:/config:Z + environment: + - AUTH_TYPE + - ENABLE_AUTH + - XMPP_DOMAIN + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_SERVER + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - JICOFO_RESERVATION_REST_BASE_URL + - JVB_BREWERY_MUC + - JIGASI_BREWERY_MUC + - JIBRI_BREWERY_MUC + - JIGASI_SIP_URI + - JIBRI_PENDING_TIMEOUT + - TZ + depends_on: + - prosody + networks: + meet.jitsi: + + # Video bridge + jvb: + image: jitsi/jvb + restart: ${RESTART_POLICY} + ports: + - '${JVB_PORT}:${JVB_PORT}/udp' + - '${JVB_TCP_MAPPED_PORT}:${JVB_TCP_PORT}' + volumes: + - ${CONFIG}/jvb:/config:Z + environment: + - DOCKER_HOST_ADDRESS + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_SERVER + - JVB_AUTH_USER + - JVB_AUTH_PASSWORD + - JVB_BREWERY_MUC + - JVB_PORT + - JVB_TCP_HARVESTER_DISABLED + - JVB_TCP_PORT + - JVB_STUN_SERVERS + - JVB_ENABLE_APIS + - TZ + depends_on: + - prosody + networks: + meet.jitsi: + +# Custom network so all services can communicate using a FQDN +networks: + meet.jitsi: + # traefik: change the following line to your external docker network + web: + external: true diff --git a/gen-passwords.sh b/gen-passwords.sh new file mode 100755 index 0000000..c05a07b --- /dev/null +++ b/gen-passwords.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +function generatePassword() { + openssl rand -hex 16 +} + +JICOFO_COMPONENT_SECRET=$(generatePassword) +JICOFO_AUTH_PASSWORD=$(generatePassword) +JVB_AUTH_PASSWORD=$(generatePassword) +JIGASI_XMPP_PASSWORD=$(generatePassword) +JIBRI_RECORDER_PASSWORD=$(generatePassword) +JIBRI_XMPP_PASSWORD=$(generatePassword) + +sed -i.bak \ + -e "s#JICOFO_COMPONENT_SECRET=.*#JICOFO_COMPONENT_SECRET=${JICOFO_COMPONENT_SECRET}#g" \ + -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" \ + "$(dirname "$0")/.env" diff --git a/jibri.yml b/jibri.yml new file mode 100644 index 0000000..67b5b98 --- /dev/null +++ b/jibri.yml @@ -0,0 +1,36 @@ +version: '3' + +services: + jibri: + image: jitsi/jibri:latest + restart: ${RESTART_POLICY} + volumes: + - ${CONFIG}/jibri:/config:Z + - /dev/shm:/dev/shm + cap_add: + - SYS_ADMIN + - NET_BIND_SERVICE + devices: + - /dev/snd:/dev/snd + environment: + - XMPP_AUTH_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_RECORDER_DOMAIN + - XMPP_SERVER + - XMPP_DOMAIN + - JIBRI_XMPP_USER + - JIBRI_XMPP_PASSWORD + - JIBRI_BREWERY_MUC + - JIBRI_RECORDER_USER + - JIBRI_RECORDER_PASSWORD + - JIBRI_RECORDING_DIR + - JIBRI_FINALIZE_RECORDING_SCRIPT_PATH + - JIBRI_STRIP_DOMAIN_JID + - JIBRI_LOGS_DIR + - DISPLAY=:0 + - TZ + depends_on: + - jicofo + networks: + meet.jitsi: + diff --git a/jibri/Dockerfile b/jibri/Dockerfile new file mode 100644 index 0000000..f1d140d --- /dev/null +++ b/jibri/Dockerfile @@ -0,0 +1,53 @@ +ARG JITSI_REPO=jitsi +FROM ${JITSI_REPO}/base-java + +#ARG CHROME_RELEASE=latest +#ARG CHROMEDRIVER_MAJOR_RELEASE=latest +ARG CHROME_RELEASE=78.0.3904.97 +ARG CHROMEDRIVER_MAJOR_RELEASE=78 + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN \ + apt-dpkg-wrap apt-get update \ + && apt-dpkg-wrap apt-get install -y jibri libgl1-mesa-dri procps \ + && apt-cleanup + +RUN \ + [ "${CHROME_RELEASE}" = "latest" ] \ + && wget -q https://dl-ssl.google.com/linux/linux_signing_key.pub -O /etc/apt/trusted.gpg.d/google.asc \ + && 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 \ + && apt-cleanup \ + || true + +RUN \ + [ "${CHROME_RELEASE}" != "latest" ] \ + && curl -4so "/tmp/google-chrome-stable_${CHROME_RELEASE}-1_amd64.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 update \ + && apt-dpkg-wrap apt-get install -y "/tmp/google-chrome-stable_${CHROME_RELEASE}-1_amd64.deb" \ + && apt-cleanup \ + || true + +RUN \ + [ "${CHROMEDRIVER_MAJOR_RELEASE}" = "latest" ] \ + && CHROMEDRIVER_RELEASE="$(curl -4Ls https://chromedriver.storage.googleapis.com/LATEST_RELEASE)" \ + || CHROMEDRIVER_RELEASE="$(curl -4Ls https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${CHROMEDRIVER_MAJOR_RELEASE})" \ + && curl -4Ls "https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_RELEASE}/chromedriver_linux64.zip" \ + | zcat >> /usr/bin/chromedriver \ + && chmod +x /usr/bin/chromedriver \ + && chromedriver --version + +RUN \ + apt-dpkg-wrap apt-get update \ + && apt-dpkg-wrap apt-get install -y jitsi-upload-integrations jq \ + && apt-cleanup + +COPY rootfs/ / + +RUN /fix-permissions.sh + +VOLUME /config + +USER 1001 diff --git a/jibri/rootfs/defaults/config.json b/jibri/rootfs/defaults/config.json new file mode 100644 index 0000000..9b55432 --- /dev/null +++ b/jibri/rootfs/defaults/config.json @@ -0,0 +1,60 @@ +{ + "recording_directory":"{{ .Env.JIBRI_RECORDING_DIR }}", + // The path to the script which will be run on completed recordings +{{ if .Env.JIBRI_FINALIZE_RECORDING_SCRIPT_PATH -}} + "finalize_recording_script_path": "{{ .Env.JIBRI_FINALIZE_RECORDING_SCRIPT_PATH }}", +{{ end -}} + "xmpp_environments": [ + { + // A friendly name for this environment which can be used + // for logging, stats, etc. + "name": "prod environment", + // The hosts of the XMPP servers to connect to as part of + // this environment + "xmpp_server_hosts": [ + "{{ .Env.XMPP_SERVER }}" + ], + "xmpp_domain": "{{ .Env.XMPP_DOMAIN }}", + // Jibri will login to the xmpp server as a privileged user + "control_login": { + "domain": "{{ .Env.XMPP_AUTH_DOMAIN }}", + // The credentials for logging in + "username": "{{ .Env.JIBRI_XMPP_USER }}", + "password": "{{ .Env.JIBRI_XMPP_PASSWORD }}" + }, + // Using the control_login information above, Jibri will join + // a control muc as a means of announcing its availability + // to provide services for a given environment + "control_muc": { + "domain": "{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}", + "room_name": "{{ .Env.JIBRI_BREWERY_MUC }}", + // MUST be unic for every instanse + "nickname": "jibri-instanse-{{ .Env.JIBRI_INSTANCE_ID }}" + }, + // All participants in a call join a muc so they can exchange + // information. Jibri can be instructed to join a special muc + // with credentials to give it special abilities (e.g. not being + // displayed to other users like a normal participant) + "call_login": { + "domain": "{{ .Env.XMPP_RECORDER_DOMAIN }}", + "username": "{{ .Env.JIBRI_RECORDER_USER }}", + "password": "{{ .Env.JIBRI_RECORDER_PASSWORD }}" + }, + // When jibri gets a request to start a service for a room, the room + // jid will look like: + // roomName@optional.prefixes.subdomain.xmpp_domain + // We'll build the url for the call by transforming that into: + // https://xmpp_domain/subdomain/roomName + // So if there are any prefixes in the jid (like jitsi meet, which + // has its participants join a muc at conference.xmpp_domain) then + // list that prefix here so it can be stripped out to generate + // the call url correctly + "room_jid_domain_string_to_strip_from_start": "{{ .Env.JIBRI_STRIP_DOMAIN_JID }}.", + // The amount of time, in minutes, a service is allowed to continue. + // Once a service has been running for this long, it will be + // stopped (cleanly). A value of 0 means an indefinite amount + // of time is allowed + "usage_timeout": "0" + } + ] +} diff --git a/jibri/rootfs/defaults/logging.properties b/jibri/rootfs/defaults/logging.properties new file mode 100644 index 0000000..ba6c34e --- /dev/null +++ b/jibri/rootfs/defaults/logging.properties @@ -0,0 +1,33 @@ +handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler + +java.util.logging.FileHandler.level = FINE +java.util.logging.FileHandler.pattern = {{ .Env.JIBRI_LOGS_DIR }}/log.%g.txt +java.util.logging.FileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter +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 = {{ .Env.JIBRI_LOGS_DIR }}/ffmpeg.%g.txt +org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter +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 = {{ .Env.JIBRI_LOGS_DIR }}/pjsua.%g.txt +org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter +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 = {{ .Env.JIBRI_LOGS_DIR }}/browser.%g.txt +org.jitsi.jibri.selenium.util.BrowserFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter +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 = net.java.sip.communicator.util.ScLogFormatter + +org.jitsi.level = FINE + +org.glassfish.level = INFO +org.osgi.level = INFO diff --git a/jibri/rootfs/etc/cont-init.d/10-config b/jibri/rootfs/etc/cont-init.d/10-config new file mode 100644 index 0000000..cd5b0f3 --- /dev/null +++ b/jibri/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,60 @@ +#!/usr/bin/with-contenv bash + +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 ) + +# check loaded snd_aloop module and exit if is not loaded on the host +[ -z "$(lsmod | grep -om1 snd_aloop)" ] \ +&& ( echo -e "\e[31mERROR: Please load snd-aloop module on the docker host.\e[39m"; kill 1; exit 1 ) + +# TODO Fix this for OpenShift +# get host's audio group id +host_audio_group="$(stat -c %g /dev/snd/pcmC0D0p 2>/dev/null)" + +# audio group is not found. Has it been run without jibri.yml? +[ -z "${host_audio_group}" ] \ +&& ( echo -e "\e[31mERROR: Binding /dev/snd is not found. Please check that you run docker-compose with -f jibri.yml.\e[39m"; kill 1; exit 1 ) + +# try to create group with this id. If group with the id already exists, just skip +groupadd -g ${host_audio_group} jibri-audio >/dev/null 2>&1 +# include user to the group by id +usermod -aG ${host_audio_group} jibri + +# 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=$(date +%N) + +# always recreate configs +tpl /defaults/config.json > /etc/jitsi/jibri/config.json +tpl /defaults/logging.properties > /etc/jitsi/jibri/logging.properties + +# make recording dir +[ -z "${JIBRI_RECORDING_DIR}" ] && export JIBRI_RECORDING_DIR=/config/recordings +mkdir -pm 770 ${JIBRI_RECORDING_DIR} + +# make logs dir +[ -z "${JIBRI_LOGS_DIR}" ] && export JIBRI_LOGS_DIR=/config/logs +mkdir -pm 770 ${JIBRI_LOGS_DIR} diff --git a/jibri/rootfs/etc/opt/chrome/policies/managed/managed_policies.json b/jibri/rootfs/etc/opt/chrome/policies/managed/managed_policies.json new file mode 100644 index 0000000..1fbf2e1 --- /dev/null +++ b/jibri/rootfs/etc/opt/chrome/policies/managed/managed_policies.json @@ -0,0 +1,4 @@ +{ + "CommandLineFlagSecurityWarningsEnabled": false +} + diff --git a/jibri/rootfs/etc/services.d/10-xorg/run b/jibri/rootfs/etc/services.d/10-xorg/run new file mode 100644 index 0000000..110867b --- /dev/null +++ b/jibri/rootfs/etc/services.d/10-xorg/run @@ -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 /bin/bash -c "exec $DAEMON" + diff --git a/jibri/rootfs/etc/services.d/20-icewm/run b/jibri/rootfs/etc/services.d/20-icewm/run new file mode 100644 index 0000000..83c80a4 --- /dev/null +++ b/jibri/rootfs/etc/services.d/20-icewm/run @@ -0,0 +1,5 @@ +#!/usr/bin/with-contenv bash + +DAEMON="/usr/bin/icewm-session" +exec /bin/bash -c "exec $DAEMON" + diff --git a/jibri/rootfs/etc/services.d/30-jibri/run b/jibri/rootfs/etc/services.d/30-jibri/run new file mode 100644 index 0000000..62afa52 --- /dev/null +++ b/jibri/rootfs/etc/services.d/30-jibri/run @@ -0,0 +1,9 @@ +#!/usr/bin/with-contenv bash + +# TODO Fix this for OpenShift +# we have to set it, otherwise chrome won't find ~/.asoundrc file +HOME=/home/jibri + +DAEMON=/opt/jitsi/jibri/launch.sh +exec /bin/bash -c "exec $DAEMON" + diff --git a/jicofo/Dockerfile b/jicofo/Dockerfile new file mode 100644 index 0000000..6421b1d --- /dev/null +++ b/jicofo/Dockerfile @@ -0,0 +1,15 @@ +ARG JITSI_REPO=jitsi +FROM ${JITSI_REPO}/base-java + +RUN \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y jicofo && \ + apt-cleanup + +COPY rootfs/ / + +RUN /fix-permissions.sh + +VOLUME /config + +USER 1001 diff --git a/jicofo/rootfs/defaults/jicofo.conf b/jicofo/rootfs/defaults/jicofo.conf new file mode 100644 index 0000000..cd7c0d2 --- /dev/null +++ b/jicofo/rootfs/defaults/jicofo.conf @@ -0,0 +1,143 @@ +{{ $ENABLE_AUTH := .Env.ENABLE_AUTH | default "0" | toBool }} +{{ $AUTH_TYPE := .Env.AUTH_TYPE | default "internal" }} +{{ $ENABLE_RECORDING := .Env.ENABLE_RECORDING | default "0" | toBool }} + +jicofo { + {{ if $ENABLE_AUTH }} + authentication { + enabled = true + // The type of authentication. Supported values are XMPP, JWT or SHIBBOLETH (default). + {{ if eq $AUTH_TYPE "jwt" }} + type = JWT + {{ else if eq $AUTH_TYPE "shibboleth" }} + type = SHIBBOLETH + {{ else }} + type = XMPP + {{ end }} + {{ if eq $AUTH_TYPE "shibboleth" }} + login-url = "shibboleth:default" + logout-url = "shibboleth:default" + {{ else }} + login-url = "{{ .Env.XMPP_DOMAIN }}" + {{ end }} + } + {{ 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 .Env.OCTO_BRIDGE_SELECTION_STRATEGY }} + selection-strategy = "{{ .Env.OCTO_BRIDGE_SELECTION_STRATEGY }}" + {{ end }} + + {{ if .Env.JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS }} + health-checks { + enabled = "{{ .Env.JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS }}" + } + {{ end }} + + brewery-jid = "{{ .Env.JVB_BREWERY_MUC }}@{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}" + } + // 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 }}" + } + {{ end }} + {{ if .Env.ENABLE_CODEC_VP9 }} + vp9 { + enabled = "{{ .Env.ENABLE_CODEC_VP9 }}" + } + {{ end }} + {{ if .Env.ENABLE_CODEC_H264 }} + h264 { + enabled = "{{ .Env.ENABLE_CODEC_H264 }}" + } + {{ end }} + } + } + + conference { + {{ if .Env.ENABLE_AUTO_OWNER }} + enable-auto-owner = "{{ .Env.ENABLE_AUTO_OWNER }}" + {{ end }} + + {{ if .Env.JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT }} + initial-timeout = "{{ .Env.JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT }}" + {{ end }} + + {{ if .Env.JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT }} + single-participant-timeout = "{{ .Env.JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT }}" + {{ 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 }}" + } + {{ end }} + + {{ if $ENABLE_RECORDING }} + jibri { + brewery-jid = "{{ .Env.JIBRI_BREWERY_MUC}}@{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}" + {{ if .Env.JIBRI_REQUEST_RETRIES }} + num-retries = "{{ .Env.JIBRI_REQUEST_RETRIES }}" + {{ end }} + {{ if .Env.JIBRI_PENDING_TIMEOUT }} + pending-timeout = "{{ .Env.JIBRI_PENDING_TIMEOUT }}" + {{ end }} + } + {{ end }} + + {{ if and .Env.JIGASI_SIP_URI .Env.JIGASI_BREWERY_MUC }} + jigasi { + brewery-jid = "{{ .Env.JIGASI_BREWERY_MUC}}@{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}" + } + {{ end }} + + octo { + id = "{{ .Env.JICOFO_SHORT_ID | default "1" }}" + } + + {{ if .Env.ENABLE_SCTP }} + sctp { + enabled = "{{ .Env.ENABLE_SCTP }}" + } + {{ end }} + + xmpp { + client { + enabled = true + hostname = "{{ .Env.XMPP_SERVER }}" + domain = "{{ .Env.XMPP_AUTH_DOMAIN }}" + username = "{{ .Env.JICOFO_AUTH_USER }}" + password = "{{ .Env.JICOFO_AUTH_PASSWORD }}" + conference-muc-jid = "{{ .Env.XMPP_MUC_DOMAIN }}" + disable-certificate-verification = true + } + } + + {{ if .Env.JICOFO_RESERVATION_ENABLED | default "false" | toBool }} + reservation { + enabled = "{{ .Env.JICOFO_RESERVATION_ENABLED }}" + base-url = "{{ .Env.JICOFO_RESERVATION_REST_BASE_URL }}" + } + {{ end }} +} diff --git a/jicofo/rootfs/defaults/logging.properties b/jicofo/rootfs/defaults/logging.properties new file mode 100644 index 0000000..f8fd21a --- /dev/null +++ b/jicofo/rootfs/defaults/logging.properties @@ -0,0 +1,21 @@ +handlers= java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = ALL +java.util.logging.ConsoleHandler.formatter = net.java.sip.communicator.util.ScLogFormatter + +net.java.sip.communicator.util.ScLogFormatter.programname=Jicofo + +.level=INFO +net.sf.level=SEVERE +net.java.sip.communicator.plugin.reconnectplugin.level=FINE +org.ice4j.level=SEVERE +org.jitsi.impl.neomedia.level=SEVERE + +# Do not worry about missing strings +net.java.sip.communicator.service.resources.AbstractResourcesService.level=SEVERE + +#net.java.sip.communicator.service.protocol.level=ALL + +# Enable debug packets logging +#org.jitsi.impl.protocol.xmpp.level=FINE + diff --git a/jicofo/rootfs/etc/cont-init.d/10-config b/jicofo/rootfs/etc/cont-init.d/10-config new file mode 100644 index 0000000..f38bb2c --- /dev/null +++ b/jicofo/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,24 @@ +#!/usr/bin/with-contenv bash + +if [[ -z $JICOFO_COMPONENT_SECRET || -z $JICOFO_AUTH_PASSWORD ]]; then + echo 'FATAL ERROR: Jicofo component secret and auth password must be set' + exit 1 +fi + +OLD_JICOFO_COMPONENT_SECRET=s3cr37 +if [[ "$JICOFO_COMPONENT_SECRET" == "$OLD_JICOFO_COMPONENT_SECRET" ]]; then + echo 'FATAL ERROR: Jicofo component secret must be changed, check the README' + 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 + +tpl /defaults/jicofo.conf > /config/jicofo.conf + +if [[ ! -f /config/logging.properties ]]; then + cp /defaults/logging.properties /config +fi diff --git a/jicofo/rootfs/etc/services.d/jicofo/run b/jicofo/rootfs/etc/services.d/jicofo/run new file mode 100644 index 0000000..b678a15 --- /dev/null +++ b/jicofo/rootfs/etc/services.d/jicofo/run @@ -0,0 +1,8 @@ +#!/usr/bin/with-contenv bash + +JAVA_SYS_PROPS="$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/jicofo.conf" +DAEMON=/usr/share/jicofo/jicofo.sh +DAEMON_DIR=/usr/share/jicofo/ +DAEMON_OPTS="--domain=$XMPP_DOMAIN --host=$XMPP_SERVER --secret=$JICOFO_COMPONENT_SECRET --user_name=$JICOFO_AUTH_USER --user_domain=$XMPP_AUTH_DOMAIN --user_password=$JICOFO_AUTH_PASSWORD" + +exec /bin/bash -c "cd $DAEMON_DIR; JAVA_SYS_PROPS=\"$JAVA_SYS_PROPS\" exec $DAEMON $DAEMON_OPTS" diff --git a/jigasi.yml b/jigasi.yml new file mode 100644 index 0000000..ed7c5b4 --- /dev/null +++ b/jigasi.yml @@ -0,0 +1,50 @@ +version: '3' + +services: + # SIP gateway (audio) + jigasi: + image: jitsi/jigasi:latest + restart: ${RESTART_POLICY} + ports: + - '${JIGASI_PORT_MIN}-${JIGASI_PORT_MAX}:${JIGASI_PORT_MIN}-${JIGASI_PORT_MAX}/udp' + volumes: + - ${CONFIG}/jigasi:/config:Z + - ${CONFIG}/transcripts:/tmp/transcripts:Z + environment: + - ENABLE_AUTH + - XMPP_AUTH_DOMAIN + - XMPP_MUC_DOMAIN + - XMPP_INTERNAL_MUC_DOMAIN + - XMPP_SERVER + - XMPP_DOMAIN + - PUBLIC_URL + - JIGASI_SIP_URI + - JIGASI_SIP_PASSWORD + - JIGASI_SIP_SERVER + - JIGASI_SIP_PORT + - JIGASI_SIP_TRANSPORT + - JIGASI_SIP_DEFAULT_ROOM + - 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 + - ENABLE_TRANSCRIPTIONS + - JIGASI_TRANSCRIBER_ADVERTISE_URL + - JIGASI_TRANSCRIBER_RECORD_AUDIO + - JIGASI_TRANSCRIBER_SEND_TXT + - GC_PROJECT_ID + - GC_PRIVATE_KEY_ID + - GC_PRIVATE_KEY + - GC_CLIENT_EMAIL + - GC_CLIENT_ID + - GC_CLIENT_CERT_URL + - TZ + depends_on: + - prosody + networks: + meet.jitsi: diff --git a/jigasi/Dockerfile b/jigasi/Dockerfile new file mode 100644 index 0000000..d4aae45 --- /dev/null +++ b/jigasi/Dockerfile @@ -0,0 +1,17 @@ +ARG JITSI_REPO=jitsi +FROM ${JITSI_REPO}/base-java + +ENV GOOGLE_APPLICATION_CREDENTIALS /config/key.json + +RUN \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y jigasi jq && \ + apt-cleanup + +COPY rootfs/ / + +RUN /fix-permissions.sh + +VOLUME ["/config", "/tmp/transcripts"] + +USER 1001 diff --git a/jigasi/rootfs/defaults/logging.properties b/jigasi/rootfs/defaults/logging.properties new file mode 100644 index 0000000..188619a --- /dev/null +++ b/jigasi/rootfs/defaults/logging.properties @@ -0,0 +1,18 @@ +handlers= java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = ALL +java.util.logging.ConsoleHandler.formatter = net.java.sip.communicator.util.ScLogFormatter + +net.java.sip.communicator.util.ScLogFormatter.programname=Jigasi + +.level=INFO +net.sf.level=SEVERE +net.java.sip.communicator.plugin.reconnectplugin.level=FINE +org.ice4j.level=SEVERE +org.jitsi.impl.neomedia.level=SEVERE + +# Do not worry about missing strings +net.java.sip.communicator.service.resources.AbstractResourcesService.level=SEVERE + +#net.java.sip.communicator.service.protocol.level=ALL + diff --git a/jigasi/rootfs/defaults/sip-communicator.properties b/jigasi/rootfs/defaults/sip-communicator.properties new file mode 100644 index 0000000..2a7abc2 --- /dev/null +++ b/jigasi/rootfs/defaults/sip-communicator.properties @@ -0,0 +1,150 @@ +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 + +# SIP account +net.java.sip.communicator.impl.protocol.sip.acc1=acc1 +{{ if and .Env.JIGASI_SIP_PORT .Env.JIGASI_SIP_TRANSPORT }} +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={{ .Env.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 +net.java.sip.communicator.impl.protocol.sip.acc1.Encodings.G722/8000=700 +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={{ .Env.XMPP_DOMAIN }} + +# XMPP account used for control +net.java.sip.communicator.impl.protocol.jabber.acc1=acc1 +net.java.sip.communicator.impl.protocol.jabber.acc1.ACCOUNT_UID=Jabber:{{ .Env.JIGASI_XMPP_USER }}@{{ .Env.XMPP_AUTH_DOMAIN }} +net.java.sip.communicator.impl.protocol.jabber.acc1.USER_ID={{ .Env.JIGASI_XMPP_USER }}@{{ .Env.XMPP_AUTH_DOMAIN }} +net.java.sip.communicator.impl.protocol.jabber.acc1.IS_SERVER_OVERRIDDEN=true +net.java.sip.communicator.impl.protocol.jabber.acc1.SERVER_ADDRESS={{ .Env.XMPP_SERVER }} +net.java.sip.communicator.impl.protocol.jabber.acc1.PASSWORD={{ .Env.JIGASI_XMPP_PASSWORD | b64enc }} +net.java.sip.communicator.impl.protocol.jabber.acc1.AUTO_GENERATE_RESOURCE=true +net.java.sip.communicator.impl.protocol.jabber.acc1.RESOURCE_PRIORITY=30 +net.java.sip.communicator.impl.protocol.jabber.acc1.IS_CARBON_DISABLED=true +net.java.sip.communicator.impl.protocol.jabber.acc1.DEFAULT_ENCRYPTION=true +net.java.sip.communicator.impl.protocol.jabber.acc1.IS_USE_ICE=true +net.java.sip.communicator.impl.protocol.jabber.acc1.IS_ACCOUNT_DISABLED=false +net.java.sip.communicator.impl.protocol.jabber.acc1.IS_PREFERRED_PROTOCOL=false +net.java.sip.communicator.impl.protocol.jabber.acc1.AUTO_DISCOVER_JINGLE_NODES=false +net.java.sip.communicator.impl.protocol.jabber.acc1.PROTOCOL=Jabber +net.java.sip.communicator.impl.protocol.jabber.acc1.IS_USE_UPNP=false +net.java.sip.communicator.impl.protocol.jabber.acc1.USE_DEFAULT_STUN_SERVER=true +net.java.sip.communicator.impl.protocol.jabber.acc1.ENCRYPTION_PROTOCOL.DTLS-SRTP=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.ENCRYPTION_PROTOCOL_STATUS.DTLS-SRTP=true +net.java.sip.communicator.impl.protocol.jabber.acc1.VIDEO_CALLING_DISABLED=true +net.java.sip.communicator.impl.protocol.jabber.acc1.OVERRIDE_ENCODINGS=true +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.G722/8000=705 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.GSM/8000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.H263-1998/90000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.H264/90000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.PCMA/8000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.PCMU/8000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.SILK/12000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.SILK/16000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.SILK/24000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.SILK/8000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.VP8/90000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.iLBC/8000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.opus/48000=750 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.speex/16000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.speex/32000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.speex/8000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.Encodings.telephone-event/8000=0 +net.java.sip.communicator.impl.protocol.jabber.acc1.BREWERY={{ .Env.JIGASI_BREWERY_MUC }}@{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }} +net.java.sip.communicator.impl.protocol.jabber.acc1.DOMAIN_BASE={{ .Env.XMPP_DOMAIN }} + +org.jitsi.jigasi.BREWERY_ENABLED=true + +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={{ .Env.XMPP_SERVER }} +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.IM_DISABLED=true +org.jitsi.jigasi.xmpp.acc.SERVER_STORED_INFO_DISABLED=true +org.jitsi.jigasi.xmpp.acc.IS_FILE_TRANSFER_DISABLED=true +{{ if .Env.ENABLE_AUTH | default "0" | toBool }} +org.jitsi.jigasi.xmpp.acc.USER_ID={{ .Env.JIGASI_XMPP_USER }}@{{ .Env.XMPP_AUTH_DOMAIN }} +org.jitsi.jigasi.xmpp.acc.PASS={{ .Env.JIGASI_XMPP_PASSWORD }} +org.jitsi.jigasi.xmpp.acc.ANONYMOUS_AUTH=false +org.jitsi.jigasi.xmpp.acc.ALLOW_NON_SECURE=true +{{ end }} + +# 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.ENABLE_TRANSCRIPTIONS | default "0" | toBool }} +# Transcription config +org.jitsi.jigasi.ENABLE_TRANSCRIPTION=true +org.jitsi.jigasi.transcription.ENABLE_TRANSLATION=true +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.SEND_JSON=true +org.jitsi.jigasi.transcription.SAVE_TXT=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 +{{end}} + +{{ 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={{ .Env.XMPP_MUC_DOMAIN }} diff --git a/jigasi/rootfs/etc/cont-init.d/10-config b/jigasi/rootfs/etc/cont-init.d/10-config new file mode 100644 index 0000000..da7e440 --- /dev/null +++ b/jigasi/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,50 @@ +#!/usr/bin/with-contenv bash + +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 + +tpl /defaults/sip-communicator.properties > /config/sip-communicator.properties +if [[ -f /config/custom-sip-communicator.properties ]]; then + cat /config/custom-sip-communicator.properties >> /config/sip-communicator.properties +fi + +if [[ ! -f /config/logging.properties ]]; then + cp /defaults/logging.properties /config +fi + +# Create Google Cloud Credentials +if [[ $ENABLE_TRANSCRIPTIONS -eq 1 || $ENABLE_TRANSCRIPTIONS == "true" ]]; then + 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 environment variables are undefined' + exit 1 + fi + + 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 diff --git a/jigasi/rootfs/etc/services.d/jigasi/run b/jigasi/rootfs/etc/services.d/jigasi/run new file mode 100644 index 0000000..2ea08ed --- /dev/null +++ b/jigasi/rootfs/etc/services.d/jigasi/run @@ -0,0 +1,9 @@ +#!/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 --max-port=$JIGASI_PORT_MAX" + +exec /bin/bash -c "JAVA_SYS_PROPS=\"$JAVA_SYS_PROPS\" exec $DAEMON $DAEMON_OPTS" + diff --git a/jvb/Dockerfile b/jvb/Dockerfile new file mode 100644 index 0000000..aaad52f --- /dev/null +++ b/jvb/Dockerfile @@ -0,0 +1,15 @@ +ARG JITSI_REPO=jitsi +FROM ${JITSI_REPO}/base-java + +RUN \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y jitsi-videobridge2 jq curl iproute2 && \ + apt-cleanup + +COPY rootfs/ / + +RUN /fix-permissions.sh + +VOLUME /config + +USER 1001 diff --git a/jvb/rootfs/defaults/jvb.conf b/jvb/rootfs/defaults/jvb.conf new file mode 100644 index 0000000..baca26c --- /dev/null +++ b/jvb/rootfs/defaults/jvb.conf @@ -0,0 +1,65 @@ +{{ $JVB_TCP_PORT := .Env.JVB_TCP_PORT | default "4443" }} +{{ $JVB_TCP_MAPPED_PORT := .Env.JVB_TCP_MAPPED_PORT | default $JVB_TCP_PORT }} +{{ $PUBLIC_URL_DOMAIN := .Env.PUBLIC_URL | default "https://localhost:8443" | trimPrefix "https://" | trimSuffix "/" -}} +{{ $WS_DOMAIN := .Env.JVB_WS_DOMAIN | default $PUBLIC_URL_DOMAIN -}} +{{ $WS_SERVER_ID := .Env.JVB_WS_SERVER_ID | default .Env.LOCAL_ADDRESS -}} + +videobridge { + ice { + udp { + port = {{ .Env.JVB_PORT }} + } + tcp { + enabled = {{ not (.Env.JVB_TCP_HARVESTER_DISABLED | default "true" | toBool) }} + port = {{ .Env.JVB_TCP_PORT }} +{{ if not (eq $JVB_TCP_PORT $JVB_TCP_MAPPED_PORT) }} + mapped-port = {{ $JVB_TCP_MAPPED_PORT }} +{{ end }} + } + } + apis { + xmpp-client { + configs { + shard { + HOSTNAME = "{{ .Env.XMPP_SERVER }}" + DOMAIN = "{{ .Env.XMPP_AUTH_DOMAIN }}" + USERNAME = "{{ .Env.JVB_AUTH_USER }}" + PASSWORD = "{{ .Env.JVB_AUTH_PASSWORD }}" + MUC_JIDS = "{{ .Env.JVB_BREWERY_MUC }}@{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}" + MUC_NICKNAME = "{{ .Env.HOSTNAME }}" + DISABLE_CERTIFICATE_VERIFICATION = true + } + } + } + } + stats { + enabled = true + } + websockets { + enabled = true + domain = "{{ $WS_DOMAIN }}" + tls = true + server-id = "{{ $WS_SERVER_ID }}" + } + http-servers { + private { + host = 0.0.0.0 + } + public { + host = 0.0.0.0 + port = 9090 + } + } +} + +ice4j { + harvest { + mapping { + stun { +{{ if .Env.JVB_STUN_SERVERS }} + addresses = [ "{{ join "\",\"" (splitList "," .Env.JVB_STUN_SERVERS) }}" ] +{{ end }} + } + } + } +} diff --git a/jvb/rootfs/defaults/logging.properties b/jvb/rootfs/defaults/logging.properties new file mode 100644 index 0000000..11f5667 --- /dev/null +++ b/jvb/rootfs/defaults/logging.properties @@ -0,0 +1,14 @@ +handlers= java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = ALL +java.util.logging.ConsoleHandler.formatter = net.java.sip.communicator.util.ScLogFormatter + +net.java.sip.communicator.util.ScLogFormatter.programname=JVB + +.level=INFO + +org.jitsi.videobridge.xmpp.ComponentImpl.level=FINE + +# All of the INFO level logs from MediaStreamImpl are unnecessary in the context of jitsi-videobridge. +org.jitsi.impl.neomedia.MediaStreamImpl.level=WARNING + diff --git a/jvb/rootfs/defaults/sip-communicator.properties b/jvb/rootfs/defaults/sip-communicator.properties new file mode 100644 index 0000000..44f45db --- /dev/null +++ b/jvb/rootfs/defaults/sip-communicator.properties @@ -0,0 +1,5 @@ +{{ if .Env.DOCKER_HOST_ADDRESS }} +org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS={{ .Env.LOCAL_ADDRESS }} +org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS={{ .Env.DOCKER_HOST_ADDRESS }} +{{ end }} + diff --git a/jvb/rootfs/etc/cont-init.d/10-config b/jvb/rootfs/etc/cont-init.d/10-config new file mode 100644 index 0000000..d413e2e --- /dev/null +++ b/jvb/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,25 @@ +#!/usr/bin/with-contenv bash + +export LOCAL_ADDRESS=$(ip addr show dev "$(ip route|awk '/^default/ { print $5 }')" | grep -oP '(?<=inet\s)\d+(\.\d+){3}') + +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 + +tpl /defaults/sip-communicator.properties > /config/sip-communicator.properties +if [[ -f /config/custom-sip-communicator.properties ]]; then + cat /config/custom-sip-communicator.properties >> /config/sip-communicator.properties +fi + +tpl /defaults/jvb.conf > /config/jvb.conf + +if [[ ! -f /config/logging.properties ]]; then + cp /defaults/logging.properties /config +fi diff --git a/jvb/rootfs/etc/services.d/jvb/run b/jvb/rootfs/etc/services.d/jvb/run new file mode 100644 index 0000000..37cc7db --- /dev/null +++ b/jvb/rootfs/etc/services.d/jvb/run @@ -0,0 +1,7 @@ +#!/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 + +exec /bin/bash -c "exec $DAEMON --apis=${JVB_ENABLE_APIS:="none"}" diff --git a/prosody/Dockerfile b/prosody/Dockerfile new file mode 100644 index 0000000..49bdb65 --- /dev/null +++ b/prosody/Dockerfile @@ -0,0 +1,70 @@ +ARG JITSI_REPO=jitsi + +FROM ${JITSI_REPO}/base as builder + +RUN \ + apt-dpkg-wrap apt-get update \ + && apt-dpkg-wrap apt-get install -y \ + lua5.2 \ + liblua5.2-dev \ + libsasl2-dev \ + libssl-dev \ + luarocks \ + git \ + gcc \ + && luarocks install cyrussasl 1.1.0-1 \ + && luarocks install net-url 0.9-1 \ + && luarocks install luajwtjitsi 2.0-0 + +FROM ${JITSI_REPO}/base + +ENV XMPP_CROSS_DOMAIN="false" + +RUN \ + wget -q https://prosody.im/files/prosody-debian-packages.key -O - | gpg --enarmor > /etc/apt/trusted.gpg.d/prosody.asc \ + && echo "deb http://packages.prosody.im/debian buster main" > /etc/apt/sources.list.d/prosody.list \ + && apt-dpkg-wrap apt-get update \ + && apt-dpkg-wrap apt-get install -y \ + prosody \ + libssl1.1 \ + sasl2-bin \ + libsasl2-modules-ldap \ + lua-basexx \ + lua-ldap \ + lua-sec \ + patch \ + && apt-cleanup \ + && rm -rf /etc/prosody + +RUN \ + apt-dpkg-wrap apt-get update \ + && 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 \ + && apt-cleanup \ + && rm -rf /tmp/pkg /var/cache/apt + +COPY rootfs/ / + +COPY --from=builder /usr/local/lib/lua /usr/local/lib/lua +COPY --from=builder /usr/local/share/lua /usr/local/share/lua + +RUN \ + patch -d /usr/lib/prosody/modules/muc -p0 < /prosody-plugins/muc_owner_allow_kick.patch && \ + patch -d /usr/bin -p1 < /prosodyctl-certdir-permission-fix.patch + +# Apply config +RUN echo "TLS_REQCERT allow" >> /etc/ldap/ldap.conf + +# Fix permissions +RUN \ + /fix-permissions.sh && \ + touch /etc/saslauthd.conf && \ + chmod g=u -R /prosody-plugins /etc/saslauthd.conf && \ + chgrp -R root /etc/sasldb2 /run/saslauthd + +EXPOSE 5222 5347 5280 + +VOLUME ["/config", "/prosody-plugins-custom"] + +USER 1001 diff --git a/prosody/rootfs/defaults/conf.d/jitsi-meet.cfg.lua b/prosody/rootfs/defaults/conf.d/jitsi-meet.cfg.lua new file mode 100644 index 0000000..06d1355 --- /dev/null +++ b/prosody/rootfs/defaults/conf.d/jitsi-meet.cfg.lua @@ -0,0 +1,184 @@ +admins = { + "{{ .Env.JICOFO_AUTH_USER }}@{{ .Env.XMPP_AUTH_DOMAIN }}", + "{{ .Env.JVB_AUTH_USER }}@{{ .Env.XMPP_AUTH_DOMAIN }}" +} + +plugin_paths = { "/prosody-plugins", "/prosody-plugins-custom" } +http_default_host = "{{ .Env.XMPP_DOMAIN }}" + +{{ $ENABLE_AUTH := .Env.ENABLE_AUTH | default "0" | toBool }} +{{ $ENABLE_GUEST_DOMAIN := and $ENABLE_AUTH (.Env.ENABLE_GUESTS | default "0" | toBool)}} +{{ $AUTH_TYPE := .Env.AUTH_TYPE | default "internal" }} +{{ $JWT_ASAP_KEYSERVER := .Env.JWT_ASAP_KEYSERVER | default "" }} +{{ $JWT_ALLOW_EMPTY := .Env.JWT_ALLOW_EMPTY | default "0" | toBool }} +{{ $JWT_AUTH_TYPE := .Env.JWT_AUTH_TYPE | default "token" }} +{{ $JWT_TOKEN_AUTH_MODULE := .Env.JWT_TOKEN_AUTH_MODULE | default "token_verification" }} +{{ $ENABLE_LOBBY := .Env.ENABLE_LOBBY | default "0" | toBool }} + +{{ $ENABLE_XMPP_WEBSOCKET := .Env.ENABLE_XMPP_WEBSOCKET | default "1" | toBool }} +{{ $PUBLIC_URL := .Env.PUBLIC_URL | default "https://localhost:8443" -}} + +{{ if and $ENABLE_AUTH (eq $AUTH_TYPE "jwt") .Env.JWT_ACCEPTED_ISSUERS }} +asap_accepted_issuers = { "{{ join "\",\"" (splitList "," .Env.JWT_ACCEPTED_ISSUERS) }}" } +{{ end }} + +{{ if and $ENABLE_AUTH (eq $AUTH_TYPE "jwt") .Env.JWT_ACCEPTED_AUDIENCES }} +asap_accepted_audiences = { "{{ join "\",\"" (splitList "," .Env.JWT_ACCEPTED_AUDIENCES) }}" } +{{ end }} + +consider_bosh_secure = true; + +-- Deprecated in 0.12 +-- https://github.com/bjc/prosody/commit/26542811eafd9c708a130272d7b7de77b92712de +{{ $XMPP_CROSS_DOMAINS := $PUBLIC_URL }} +{{ $XMPP_CROSS_DOMAIN := .Env.XMPP_CROSS_DOMAIN | default "" }} +{{ if eq $XMPP_CROSS_DOMAIN "true"}} +cross_domain_websocket = true +cross_domain_bosh = true +{{ else }} +{{ if not (eq $XMPP_CROSS_DOMAIN "false") }} + {{ $XMPP_CROSS_DOMAINS = list $PUBLIC_URL (print "https://" .Env.XMPP_DOMAIN) .Env.XMPP_CROSS_DOMAIN | join "," }} +{{ end }} +cross_domain_websocket = { "{{ join "\",\"" (splitList "," $XMPP_CROSS_DOMAINS) }}" } +cross_domain_bosh = { "{{ join "\",\"" (splitList "," $XMPP_CROSS_DOMAINS) }}" } +{{ end }} + +VirtualHost "{{ .Env.XMPP_DOMAIN }}" +{{ if $ENABLE_AUTH }} + {{ if eq $AUTH_TYPE "jwt" }} + authentication = "{{ $JWT_AUTH_TYPE }}" + app_id = "{{ .Env.JWT_APP_ID }}" + app_secret = "{{ .Env.JWT_APP_SECRET }}" + allow_empty_token = {{ if $JWT_ALLOW_EMPTY }}true{{ else }}false{{ end }} + {{ if $JWT_ASAP_KEYSERVER }} + asap_key_server = "{{ .Env.JWT_ASAP_KEYSERVER }}" + {{ end }} + + {{ else if eq $AUTH_TYPE "ldap" }} + authentication = "cyrus" + cyrus_application_name = "xmpp" + allow_unencrypted_plain_auth = true + {{ else if eq $AUTH_TYPE "internal" }} + authentication = "internal_hashed" + {{ end }} +{{ else }} + -- https://github.com/jitsi/docker-jitsi-meet/pull/502#issuecomment-619146339 + {{ if $ENABLE_XMPP_WEBSOCKET }} + authentication = "token" + {{ else }} + authentication = "anonymous" + {{ end }} + app_id = "" + app_secret = "" + allow_empty_token = true +{{ end }} + ssl = { + key = "/config/certs/{{ .Env.XMPP_DOMAIN }}.key"; + certificate = "/config/certs/{{ .Env.XMPP_DOMAIN }}.crt"; + } + modules_enabled = { + "bosh"; + {{ if $ENABLE_XMPP_WEBSOCKET }} + "websocket"; + "smacks"; -- XEP-0198: Stream Management + {{ end }} + "pubsub"; + "ping"; + "speakerstats"; + "conference_duration"; + {{ if $ENABLE_LOBBY }} + "muc_lobby_rooms"; + {{ end }} + {{ if .Env.XMPP_MODULES }} + "{{ join "\";\n\"" (splitList "," .Env.XMPP_MODULES) }}"; + {{ end }} + {{ if and $ENABLE_AUTH (eq $AUTH_TYPE "ldap") }} + "auth_cyrus"; + {{end}} + } + + {{ if $ENABLE_LOBBY }} + main_muc = "{{ .Env.XMPP_MUC_DOMAIN }}" + lobby_muc = "lobby.{{ .Env.XMPP_DOMAIN }}" + {{ if .Env.XMPP_RECORDER_DOMAIN }} + muc_lobby_whitelist = { "{{ .Env.XMPP_RECORDER_DOMAIN }}" } + {{ end }} + {{ end }} + + speakerstats_component = "speakerstats.{{ .Env.XMPP_DOMAIN }}" + conference_duration_component = "conferenceduration.{{ .Env.XMPP_DOMAIN }}" + + c2s_require_encryption = false + +{{ if $ENABLE_GUEST_DOMAIN }} +VirtualHost "{{ .Env.XMPP_GUEST_DOMAIN }}" + -- https://github.com/jitsi/docker-jitsi-meet/pull/502#issuecomment-619146339 + {{ if $ENABLE_XMPP_WEBSOCKET }} + authentication = "token" + {{ else }} + authentication = "anonymous" + {{ end }} + app_id = "" + app_secret = "" + allow_empty_token = true + + c2s_require_encryption = false +{{ end }} + +VirtualHost "{{ .Env.XMPP_AUTH_DOMAIN }}" + ssl = { + key = "/config/certs/{{ .Env.XMPP_AUTH_DOMAIN }}.key"; + certificate = "/config/certs/{{ .Env.XMPP_AUTH_DOMAIN }}.crt"; + } + authentication = "internal_hashed" + +{{ if .Env.XMPP_RECORDER_DOMAIN }} +VirtualHost "{{ .Env.XMPP_RECORDER_DOMAIN }}" + modules_enabled = { + "ping"; + } + authentication = "internal_hashed" +{{ end }} + +Component "{{ .Env.XMPP_INTERNAL_MUC_DOMAIN }}" "muc" + storage = "memory" + modules_enabled = { + "ping"; + {{ if .Env.XMPP_INTERNAL_MUC_MODULES }} + "{{ join "\";\n\"" (splitList "," .Env.XMPP_INTERNAL_MUC_MODULES) }}"; + {{ end }} + } + muc_room_locking = false + muc_room_default_public_jids = true + +Component "{{ .Env.XMPP_MUC_DOMAIN }}" "muc" + storage = "memory" + modules_enabled = { + "muc_meeting_id"; + {{ if .Env.XMPP_MUC_MODULES }} + "{{ join "\";\n\"" (splitList "," .Env.XMPP_MUC_MODULES) }}"; + {{ end }} + {{ if and $ENABLE_AUTH (eq $AUTH_TYPE "jwt") }} + "{{ $JWT_TOKEN_AUTH_MODULE }}"; + {{ end }} + } + muc_room_cache_size = 1000 + muc_room_locking = false + muc_room_default_public_jids = true + +Component "focus.{{ .Env.XMPP_DOMAIN }}" + component_secret = "{{ .Env.JICOFO_COMPONENT_SECRET }}" + +Component "speakerstats.{{ .Env.XMPP_DOMAIN }}" "speakerstats_component" + muc_component = "{{ .Env.XMPP_MUC_DOMAIN }}" + +Component "conferenceduration.{{ .Env.XMPP_DOMAIN }}" "conference_duration_component" + muc_component = "{{ .Env.XMPP_MUC_DOMAIN }}" + +{{ if $ENABLE_LOBBY }} +Component "lobby.{{ .Env.XMPP_DOMAIN }}" "muc" + storage = "memory" + restrict_room_creation = true + muc_room_locking = false + muc_room_default_public_jids = true +{{ end }} diff --git a/prosody/rootfs/defaults/prosody.cfg.lua b/prosody/rootfs/defaults/prosody.cfg.lua new file mode 100644 index 0000000..6c7687c --- /dev/null +++ b/prosody/rootfs/defaults/prosody.cfg.lua @@ -0,0 +1,172 @@ +{{ $LOG_LEVEL := .Env.LOG_LEVEL | default "info" }} + +-- Prosody Example Configuration File +-- +-- Information on configuring Prosody can be found on our +-- website at http://prosody.im/doc/configure +-- +-- Tip: You can check that the syntax of this file is correct +-- when you have finished by running: luac -p prosody.cfg.lua +-- If there are any errors, it will let you know what and where +-- they are, otherwise it will keep quiet. +-- +-- The only thing left to do is rename this file to remove the .dist ending, and fill in the +-- blanks. Good luck, and happy Jabbering! + + +---------- Server-wide settings ---------- +-- Settings in this section apply to the whole server and are the default settings +-- for any virtual hosts + +-- This is a (by default, empty) list of accounts that are admins +-- for the server. Note that you must create the accounts separately +-- (see http://prosody.im/doc/creating_accounts for info) +-- Example: admins = { "user1@example.com", "user2@example.net" } +admins = { } + +-- Enable use of libevent for better performance under high load +-- For more information see: http://prosody.im/doc/libevent +--use_libevent = true; + +-- This is the list of modules Prosody will load on startup. +-- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too. +-- Documentation on modules can be found at: http://prosody.im/doc/modules +modules_enabled = { + + -- Generally required + "roster"; -- Allow users to have a roster. Recommended ;) + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "tls"; -- Add support for secure TLS on c2s/s2s connections + "dialback"; -- s2s dialback support + "disco"; -- Service discovery + + -- Not essential, but recommended + "private"; -- Private XML storage (for room bookmarks, etc.) + "vcard"; -- Allow users to set vCards + + -- These are commented by default as they have a performance impact + --"privacy"; -- Support privacy lists + --"compression"; -- Stream compression (Debian: requires lua-zlib module to work) + + -- Nice to have + "version"; -- Replies to server version requests + "uptime"; -- Report how long server has been running + "time"; -- Let others know the time here on this server + "ping"; -- Replies to XMPP pings with pongs + "pep"; -- Enables users to publish their mood, activity, playing music and more + "register"; -- Allow users to register on this server using a client and change passwords + + -- Admin interfaces + "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands + --"admin_telnet"; -- Opens telnet console interface on localhost port 5582 + + -- HTTP modules + --"bosh"; -- Enable BOSH clients, aka "Jabber over HTTP" + --"http_files"; -- Serve static files from a directory over HTTP + + -- Other specific functionality + "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. + --"groups"; -- Shared roster support + --"announce"; -- Send announcement to all online users + --"welcome"; -- Welcome users who register accounts + --"watchregistrations"; -- Alert admins of registrations + --"motd"; -- Send a message to users when they log in + --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots. + {{ if .Env.GLOBAL_MODULES }} + "{{ join "\";\n\"" (splitList "," .Env.GLOBAL_MODULES) }}"; + {{ end }} +}; + +https_ports = { } + +-- These modules are auto-loaded, but should you want +-- to disable them then uncomment them here: +modules_disabled = { + -- "offline"; -- Store offline messages + -- "c2s"; -- Handle client connections + "s2s"; -- Handle server-to-server connections +}; + +-- Disable account creation by default, for security +-- For more information see http://prosody.im/doc/creating_accounts +allow_registration = false; + +daemonize = false; + +-- Force clients to use encrypted connections? This option will +-- prevent clients from authenticating unless they are using encryption. + +c2s_require_encryption = false + +-- Force certificate authentication for server-to-server connections? +-- This provides ideal security, but requires servers you communicate +-- with to support encryption AND present valid, trusted certificates. +-- NOTE: Your version of LuaSec must support certificate verification! +-- For more information see http://prosody.im/doc/s2s#security + +s2s_secure_auth = false + +-- Many servers don't support encryption or have invalid or self-signed +-- certificates. You can list domains here that will not be required to +-- authenticate using certificates. They will be authenticated using DNS. + +--s2s_insecure_domains = { "gmail.com" } + +-- Even if you leave s2s_secure_auth disabled, you can still require valid +-- certificates for some domains by specifying a list here. + +--s2s_secure_domains = { "jabber.org" } + +-- Select the authentication backend to use. The 'internal' providers +-- use Prosody's configured data storage to store the authentication data. +-- To allow Prosody to offer secure authentication mechanisms to clients, the +-- default provider stores passwords in plaintext. If you do not trust your +-- server please see http://prosody.im/doc/modules/mod_auth_internal_hashed +-- for information about using the hashed backend. + +authentication = "internal_hashed" + +-- Select the storage backend to use. By default Prosody uses flat files +-- in its configured data directory, but it also supports more backends +-- through modules. An "sql" backend is included by default, but requires +-- additional dependencies. See http://prosody.im/doc/storage for more info. + +--storage = "sql" -- Default is "internal" (Debian: "sql" requires one of the +-- lua-dbi-sqlite3, lua-dbi-mysql or lua-dbi-postgresql packages to work) + +-- For the "sql" backend, you can uncomment *one* of the below to configure: +--sql = { driver = "SQLite3", database = "prosody.sqlite" } -- Default. 'database' is the filename. +--sql = { driver = "MySQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" } +--sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" } + +-- Logging configuration +-- For advanced logging see http://prosody.im/doc/logging +-- +-- Debian: +-- Logs info and higher to /var/log +-- Logs errors to syslog also +log = { + { levels = {min = "{{ $LOG_LEVEL }}"}, to = "console"}; +} + +{{ if .Env.GLOBAL_CONFIG }} +{{ join "\n" (splitList "\\n" .Env.GLOBAL_CONFIG) }} +{{ end }} + +-- Enable use of native prosody 0.11 support for epoll over select +network_backend = "epoll"; +-- Set the TCP backlog to 511 since the kernel rounds it up to the next power of 2: 512. +network_settings = { + tcp_backlog = 511; +} + +component_interface = { "*" } + +data_path = "/config/data" + +smacks_max_unacked_stanzas = 5; +smacks_hibernation_time = 60; +smacks_max_hibernated_sessions = 1; +smacks_max_old_sessions = 1; + +Include "conf.d/*.cfg.lua" diff --git a/prosody/rootfs/defaults/saslauthd.conf b/prosody/rootfs/defaults/saslauthd.conf new file mode 100644 index 0000000..79f38d4 --- /dev/null +++ b/prosody/rootfs/defaults/saslauthd.conf @@ -0,0 +1,26 @@ +{{ if eq (.Env.AUTH_TYPE | default "internal") "ldap" }} +ldap_servers: {{ .Env.LDAP_URL }} +ldap_search_base: {{ .Env.LDAP_BASE }} +{{ if .Env.LDAP_BINDDN | default "" }} +ldap_bind_dn: {{ .Env.LDAP_BINDDN }} +ldap_bind_pw: {{ .Env.LDAP_BINDPW }} +{{ end }} +ldap_filter: {{ .Env.LDAP_FILTER | default "uid=%u" }} +ldap_version: {{ .Env.LDAP_VERSION | default "3" }} +ldap_auth_method: {{ .Env.LDAP_AUTH_METHOD | default "bind" }} + {{ if .Env.LDAP_USE_TLS | default "0" | toBool }} +ldap_tls_key: /config/certs/{{ .Env.XMPP_DOMAIN }}.key +ldap_tls_cert: /config/certs/{{ .Env.XMPP_DOMAIN }}.crt + {{ if .Env.LDAP_TLS_CHECK_PEER | default "0" | toBool }} +ldap_tls_check_peer: yes +ldap_tls_cacert_file: {{ .Env.LDAP_TLS_CACERT_FILE | default "/etc/ssl/certs/ca-certificates.crt" }} +ldap_tls_cacert_dir: {{ .Env.LDAP_TLS_CACERT_DIR | default "/etc/ssl/certs" }} + {{ end }} + {{ if .Env.LDAP_TLS_CIPHERS }} +ldap_tls_ciphers: {{ .Env.LDAP_TLS_CIPHERS }} + {{ end }} + {{ end }} +{{ end }} +{{ if .Env.LDAP_START_TLS | default "0" | toBool }} +ldap_start_tls: yes +{{ end }} diff --git a/prosody/rootfs/etc/cont-init.d/10-config b/prosody/rootfs/etc/cont-init.d/10-config new file mode 100755 index 0000000..e54cf43 --- /dev/null +++ b/prosody/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,78 @@ +#!/usr/bin/with-contenv bash + +if [[ ! -f /etc/saslauthd.conf ]]; then + tpl /defaults/saslauthd.conf > /etc/saslauthd.conf +fi + +PROSODY_CFG="/config/prosody.cfg.lua" + +if [[ ! -d /config/data ]]; then + mkdir -pm 770 /config/data +fi + +cp -r /defaults/* /config +tpl /defaults/prosody.cfg.lua > $PROSODY_CFG +tpl /defaults/conf.d/jitsi-meet.cfg.lua > /config/conf.d/jitsi-meet.cfg.lua + +if [[ -z $JICOFO_COMPONENT_SECRET || -z $JICOFO_AUTH_PASSWORD ]]; then + echo 'FATAL ERROR: Jicofo component secret and auth password must be set' + exit 1 +fi + +prosodyctl --config $PROSODY_CFG register $JICOFO_AUTH_USER $XMPP_AUTH_DOMAIN $JICOFO_AUTH_PASSWORD + +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 + +prosodyctl --config $PROSODY_CFG register $JVB_AUTH_USER $XMPP_AUTH_DOMAIN $JVB_AUTH_PASSWORD + +if [[ ! -z $JIBRI_XMPP_USER ]] && [[ ! -z $JIBRI_XMPP_PASSWORD ]]; then + 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 + prosodyctl --config $PROSODY_CFG register $JIBRI_XMPP_USER $XMPP_AUTH_DOMAIN $JIBRI_XMPP_PASSWORD +fi + +if [[ ! -z $JIBRI_RECORDER_USER ]] && [[ ! -z $JIBRI_RECORDER_PASSWORD ]]; then + 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 + prosodyctl --config $PROSODY_CFG register $JIBRI_RECORDER_USER $XMPP_RECORDER_DOMAIN $JIBRI_RECORDER_PASSWORD +fi + +if [[ ! -z $JIGASI_XMPP_USER ]] && [[ ! -z $JIGASI_XMPP_PASSWORD ]]; then + 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 + prosodyctl --config $PROSODY_CFG register $JIGASI_XMPP_USER $XMPP_AUTH_DOMAIN $JIGASI_XMPP_PASSWORD +fi + +mkdir -p /config/certs + +if [[ ! -f /config/certs/$XMPP_DOMAIN.crt ]]; then + # echo for using all default values + echo | prosodyctl --config $PROSODY_CFG cert generate $XMPP_DOMAIN +fi + +if [[ ! -f /config/certs/$XMPP_AUTH_DOMAIN.crt ]]; then + # echo for using all default values + echo | prosodyctl --config $PROSODY_CFG cert generate $XMPP_AUTH_DOMAIN +fi + +# certs will be created in /config/data +mv /config/data/*.{crt,key} /config/certs/ || true +rm -f /config/data/*.cnf diff --git a/prosody/rootfs/etc/sasl/xmpp.conf b/prosody/rootfs/etc/sasl/xmpp.conf new file mode 100644 index 0000000..c91a0c7 --- /dev/null +++ b/prosody/rootfs/etc/sasl/xmpp.conf @@ -0,0 +1,2 @@ +pwcheck_method: saslauthd +mech_list: PLAIN diff --git a/prosody/rootfs/etc/services.d/10-saslauthd/run b/prosody/rootfs/etc/services.d/10-saslauthd/run new file mode 100755 index 0000000..52e5668 --- /dev/null +++ b/prosody/rootfs/etc/services.d/10-saslauthd/run @@ -0,0 +1,2 @@ +#!/usr/bin/with-contenv bash +exec saslauthd -a ldap -O /etc/saslauthd.conf -c -m /var/run/saslauthd -n 5 -d diff --git a/prosody/rootfs/etc/services.d/prosody/run b/prosody/rootfs/etc/services.d/prosody/run new file mode 100755 index 0000000..4ee6c56 --- /dev/null +++ b/prosody/rootfs/etc/services.d/prosody/run @@ -0,0 +1,3 @@ +#!/usr/bin/with-contenv bash +exec prosody --config /config/prosody.cfg.lua + diff --git a/prosody/rootfs/prosodyctl-certdir-permission-fix.patch b/prosody/rootfs/prosodyctl-certdir-permission-fix.patch new file mode 100644 index 0000000..4cf7914 --- /dev/null +++ b/prosody/rootfs/prosodyctl-certdir-permission-fix.patch @@ -0,0 +1,27 @@ +diff --git a/prosodyctl b/prosodyctl +index 964285a..0fcf2a5 100755 +--- a/prosodyctl ++++ b/prosodyctl +@@ -803,15 +803,17 @@ function commands.cert(arg) + return 1; -- TODO Should we create it? + end + local uid = pposix.getuid(); +- if uid ~= 0 and uid ~= cert_dir_attrs.uid then +- show_warning("The directory "..cert_basedir.." is not owned by the current user, won't be able to write files to it"); ++ local gid = pposix.getgid(); ++ if uid ~= 0 and not ( ++ (cert_dir_attrs.permissions:match("^.w.......$") and uid == cert_dir_attrs.uid) or ++ (cert_dir_attrs.permissions:match("^....w....$") and gid == cert_dir_attrs.gid) or ++ cert_dir_attrs.permissions:match("^.......w.$") ++ ) then ++ show_warning("The directory "..cert_basedir.." is not writable by this user"); + return 1; + elseif not cert_dir_attrs.permissions then -- COMPAT with LuaFilesystem < 1.6.2 (hey CentOS!) + show_message("Unable to check permissions on "..cert_basedir.." (LuaFilesystem 1.6.2+ required)"); + show_message("Please confirm that Prosody (and only Prosody) can write to this directory)"); +- elseif cert_dir_attrs.permissions:match("^%.w..%-..%-.$") then +- show_warning("The directory "..cert_basedir.." not only writable by its owner"); +- return 1; + end + local subcmd = table.remove(arg, 1); + if type(cert_commands[subcmd]) == "function" then diff --git a/release.sh b/release.sh new file mode 100755 index 0000000..3c6998c --- /dev/null +++ b/release.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -e + +# Don't start a release if the tree is dirty +# + +if [[ ! -z $(git status -s) ]]; then + echo "Git tree is not clean, aborting release!" + exit 1 +fi + +# Get version and branch (we only do stable for now) +# + +V="$1" +RELEASE="${2:-stable}" + +if [[ -z $V ]]; then + echo "A version must be specified!" + exit 1 +fi + +VERSION="${RELEASE}-${V}" +echo "Releasing ${VERSION}" + +if git rev-parse "${VERSION}" >/dev/null 2>&1; then + echo "Tag for such version already exists!" + exit 1 +fi + +# Prepare changelog +# + +LAST_VERSION=$(git describe --tags --abbrev=0) +CHANGES=$(git log --oneline --no-decorate --no-merges ${LAST_VERSION}..HEAD --pretty=format:"%x2a%x20%h%x20%s") + +echo "Changelog:" +echo "$CHANGES" + +echo -e "## ${VERSION}\n\nBased on ${RELEASE} release ${V}.\n\n${CHANGES}\n" > tmp +cat CHANGELOG.md >> tmp +mv tmp CHANGELOG.md + +# Set specific image tags in compose files +# + +sed -i "" -e "s/latest/${VERSION}/" *.yml + +# Commit all changes and tag the repo +# + +git commit -a -m "release: ${VERSION}" -m "${CHANGES}" +git tag -a "${VERSION}" -m "release" -m "${CHANGES}" + +# Tag Docker images and push them to DockerHub +# + +JITSI_BUILD=${VERSION} make release + +# Revert back to "latest" for development +# + +sed -i "" -e "s/${VERSION}/latest/" *.yml + +git commit -a -m "misc: working on latest" + +# Push all changes and tags +# + +git push +git push --tags diff --git a/resources/docker-jitsi-meet.png b/resources/docker-jitsi-meet.png new file mode 100644 index 0000000000000000000000000000000000000000..ce3043b9672ffd64bfe2852b97dafc5e791016f6 GIT binary patch literal 124909 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%0DJ~^OCOPVBS!M!(toH1<#`~pgZ$Zw0F6B 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 \ No newline at end of file diff --git a/resources/jitsi-docker.png b/resources/jitsi-docker.png new file mode 100644 index 0000000000000000000000000000000000000000..d355a276df6ee4d9e0318ebd096b6f9cdd318fae GIT binary patch literal 64130 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"; +if (subdomain) { + subdomain = subdomain.substr(0,subdomain.length-1).split('.').join('_').toLowerCase() + '.'; +} +config.hosts.muc = '{{ $XMPP_MUC_DOMAIN_PREFIX }}.'+subdomain+'{{ $XMPP_DOMAIN }}'; +{{ else -}} +config.hosts.muc = '{{ $XMPP_MUC_DOMAIN }}'; +{{ end -}} + +{{ if $ENABLE_AUTH -}} +{{ if $ENABLE_GUESTS -}} +// When using authentication, domain for guest users. +config.hosts.anonymousdomain = '{{ .Env.XMPP_GUEST_DOMAIN }}'; +{{ end -}} +// Domain for authenticated users. Defaults to . +config.hosts.authdomain = '{{ $XMPP_DOMAIN }}'; +{{ end -}} + +config.bosh = '/http-bind'; +{{ if $ENABLE_XMPP_WEBSOCKET -}} +config.websocket = 'wss://{{ $PUBLIC_URL_DOMAIN }}/xmpp-websocket'; +{{ end -}} + +{{ if $CONFIG_EXTERNAL_CONNECT -}} +{{ if $ENABLE_SUBDOMAINS -}} +config.externalConnectUrl = '/http-pre-bind'; +{{ else -}} +config.externalConnectUrl = '/http-pre-bind'; +{{ end -}} +{{ end -}} diff --git a/web/rootfs/etc/cont-init.d/10-config b/web/rootfs/etc/cont-init.d/10-config new file mode 100644 index 0000000..f0760d4 --- /dev/null +++ b/web/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,95 @@ +#!/usr/bin/with-contenv bash + +# make our folders +mkdir -p \ + /config/{nginx/site-confs,keys} \ + /var/lib/nginx/tmp/client_body \ + /var/tmp/nginx + +# generate keys (maybe) +if [[ $DISABLE_HTTPS -ne 1 ]]; then + if [[ $ENABLE_LETSENCRYPT -eq 1 ]]; then + if [[ ! -f /config/acme.sh/acme.sh ]]; then + mkdir /config/acme.sh + pushd /opt + sh ./acme.sh --install --home /config/acme.sh --accountemail $LETSENCRYPT_EMAIL + popd + fi + if [[ ! -f /config/acme-certs/$LETSENCRYPT_DOMAIN/fullchain.pem ]]; then + STAGING="" + if [[ $LETSENCRYPT_USE_STAGING -eq 1 ]]; then + STAGING="--staging" + fi + export LE_WORKING_DIR="/config/acme.sh" + # TODO: move away from standalone mode to webroot mode. + /config/acme.sh/acme.sh \ + $STAGING \ + --issue \ + --standalone \ + --pre-hook "if [[ -f /var/run/s6/services/nginx ]]; then s6-svc -d /var/run/s6/services/nginx; fi" \ + --post-hook "if [[ -f /var/run/s6/services/nginx ]]; then s6-svc -u /var/run/s6/services/nginx; fi" \ + -d $LETSENCRYPT_DOMAIN + rc=$? + if [[ $rc -eq 1 ]]; then + echo "Failed to obtain a certificate from the Let's Encrypt CA." + # this tries to get the user's attention and to spare the + # authority's rate limit: + sleep 15 + echo "Exiting." + exit 1 + fi + mkdir -p /config/acme-certs/$LETSENCRYPT_DOMAIN + if ! /config/acme.sh/acme.sh \ + --install-cert -d $LETSENCRYPT_DOMAIN \ + --key-file /config/acme-certs/$LETSENCRYPT_DOMAIN/key.pem \ + --fullchain-file /config/acme-certs/$LETSENCRYPT_DOMAIN/fullchain.pem ; then + echo "Failed to install certificate." + # this tries to get the user's attention and to spare the + # authority's rate limit: + sleep 15 + echo "Exiting." + exit 1 + fi + fi + else + # use self-signed certs + if [[ -f /config/keys/cert.key && -f /config/keys/cert.crt ]]; then + echo "using keys found in /config/keys" + else + echo "generating self-signed keys in /config/keys, you can replace these with your own keys if required" + SUBJECT="/C=US/ST=TX/L=Austin/O=jitsi.org/OU=Jitsi Server/CN=*" + openssl req -new -x509 -days 3650 -nodes -out /config/keys/cert.crt -keyout /config/keys/cert.key -subj "$SUBJECT" + fi + fi +fi + +# copy config files +tpl /defaults/nginx.conf > /config/nginx/nginx.conf + +tpl /defaults/meet.conf > /config/nginx/meet.conf +if [[ -f /config/nginx/custom-meet.conf ]]; then + cat /config/nginx/custom-meet.conf >> /config/nginx/meet.conf +fi + +tpl /defaults/ssl.conf > /config/nginx/ssl.conf + +tpl /defaults/default > /config/nginx/site-confs/default + +cp /defaults/config.js /config/config.js +tpl /defaults/system-config.js >> /config/config.js +tpl /defaults/settings-config.js >> /config/config.js +if [[ -f /config/custom-config.js ]]; then + cat /config/custom-config.js >> /config/config.js +fi + +if [[ ! -f /config/interface_config.js ]]; then + cp /defaults/interface_config.js /config/interface_config.js + + # It will remove parameter 'closedcaptions' from TOOLBAR_BUTTONS if ENABLE_TRANSCRIPTIONS is false, + # because it enabled by default, but not supported out of the box. + if [[ $ENABLE_TRANSCRIPTIONS -ne 1 && "$ENABLE_TRANSCRIPTIONS" != "true" ]]; then + sed -i \ + -e "s#'closedcaptions', ##" \ + /config/interface_config.js + fi +fi diff --git a/web/rootfs/etc/services.d/cron/run b/web/rootfs/etc/services.d/cron/run new file mode 100755 index 0000000..d08f5f2 --- /dev/null +++ b/web/rootfs/etc/services.d/cron/run @@ -0,0 +1,10 @@ +#!/usr/bin/with-contenv bash + +if [[ $DISABLE_HTTPS -ne 1 ]] && \ + [[ $ENABLE_LETSENCRYPT -eq 1 ]]; then + exec cron -f +else + # if cron should not be started, + # prevent s6 from restarting this script again and again + s6-svc -O /var/run/s6/services/cron +fi diff --git a/web/rootfs/etc/services.d/nginx/run b/web/rootfs/etc/services.d/nginx/run new file mode 100644 index 0000000..884aeb9 --- /dev/null +++ b/web/rootfs/etc/services.d/nginx/run @@ -0,0 +1,3 @@ +#!/usr/bin/with-contenv bash + +exec nginx -c /config/nginx/nginx.conf