commit 467a149cbb3102374b7664af7549780f5c0d2494 Author: Saúl Ibarra Corretgé Date: Wed Mar 14 10:23:13 2018 +0100 Initial import diff --git a/base-java/Dockerfile b/base-java/Dockerfile new file mode 100644 index 0000000..2d18fef --- /dev/null +++ b/base-java/Dockerfile @@ -0,0 +1,8 @@ +FROM jitsi/base + +RUN \ + mkdir -p /usr/share/man/man1 && \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y openjdk-8-jre-headless && \ + apt-cleanup + diff --git a/base/Dockerfile b/base/Dockerfile new file mode 100644 index 0000000..cad2646 --- /dev/null +++ b/base/Dockerfile @@ -0,0 +1,23 @@ +FROM debian:stretch-slim + +ARG JITSI_RELEASE=unstable + +ADD https://github.com/just-containers/s6-overlay/releases/download/v1.21.2.2/s6-overlay-amd64.tar.gz /tmp/s6-overlay.tar.gz +ADD https://download.jitsi.org/jitsi-key.gpg.key /tmp/jitsi.key + +COPY rootfs / + +RUN \ + tar xfz /tmp/s6-overlay.tar.gz -C / && \ + rm -f /tmp/*.tar.gz && \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y apt-transport-https ca-certificates gnupg && \ + apt-key add /tmp/jitsi.key && \ + rm -f /tmp/jitsi.key && \ + echo "deb https://download.jitsi.org $JITSI_RELEASE/" > /etc/apt/sources.list.d/jitsi.list && \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get dist-upgrade -y && \ + apt-dpkg-wrap apt-get autoremove -y --purge gnupg && \ + apt-cleanup + +ENTRYPOINT [ "/init" ] diff --git a/base/README.md b/base/README.md new file mode 100644 index 0000000..47814c1 --- /dev/null +++ b/base/README.md @@ -0,0 +1,14 @@ +# Debian S6 + +This is a base Debian image with the [S6 Overlay](https://github.com/just-containers/s6-overlay). + +## Usage + +See the [S6 Overlay Documentation](https://github.com/just-containers/s6-overlay) for details on how to manage services. + +### Parameters + +These can be set using environment variables: + +* ``TZ``: timezone, defaults to "Europe/Amsterdam". + 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..eab74dc --- /dev/null +++ b/base/rootfs/etc/apt/apt.conf.d/99local @@ -0,0 +1,4 @@ +Dir::Cache ""; +Dir::Cache::archives ""; +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 100644 index 0000000..957a7b6 --- /dev/null +++ b/base/rootfs/etc/cont-init.d/01-set-timezone @@ -0,0 +1,6 @@ +#!/usr/bin/with-contenv sh + +if [ $TZ ]; then + [ -f /usr/share/zoneinfo/$TZ ] && cp /usr/share/zoneinfo/$TZ /etc/localtime || echo "WARNING: $TZ is not a valid time zone." + [ -f /usr/share/zoneinfo/$TZ ] && echo "$TZ" > /etc/timezone +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/usr/bin/apt-cleanup b/base/rootfs/usr/bin/apt-cleanup new file mode 100755 index 0000000..af92012 --- /dev/null +++ b/base/rootfs/usr/bin/apt-cleanup @@ -0,0 +1,4 @@ +#!/bin/sh + +rm -f /*.deb +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/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5c4c9f6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,77 @@ +version: '3' + +services: + # Frontend + web: + image: jitsi/web + ports: + - '8000:80' + - '8443:443' + volumes: + - ${CONFIG}/meet:/config + environment: + - XMPP_DOMAIN + - XMPP_BOSH_URL_BASE=http://prosody.meet.jitsi:5280 + - TZ + networks: + meet.jitsi: + aliases: + - web.meet.jitsi + # XMPP server + prosody: + image: jitsi/prosody + expose: + - '5222' + - '5347' + - '5280' + ports: + - '127.0.0.1:5347:5347' + volumes: + - ${CONFIG}/prosody:/config + environment: + - XMPP_DOMAIN + - JICOFO_COMPONENT_SECRET + - JVB_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - TZ + networks: + meet.jitsi: + aliases: + - prosody.meet.jitsi + # Focus component + jicofo: + image: jitsi/jicofo + volumes: + - ${CONFIG}/jicofo:/config + environment: + - XMPP_DOMAIN + - XMPP_SERVER=prosody.meet.jitsi + - JICOFO_COMPONENT_SECRET + - JICOFO_AUTH_USER + - JICOFO_AUTH_PASSWORD + - TZ + networks: + meet.jitsi: + + # Video bridge + jvb: + image: jitsi/jvb + ports: + - "10000:10000/udp" + - "4443:4443" + volumes: + - ${CONFIG}/jvb:/config + environment: + - XMPP_DOMAIN + - XMPP_SERVER=127.0.0.1 + - JVB_COMPONENT_SECRET + - JVB_STUN_SERVERS + - JICOFO_AUTH_USER + - TZ + network_mode: 'host' + +# Custom network so all services can communicate using a FQDN +networks: + meet.jitsi: + diff --git a/jicofo/Dockerfile b/jicofo/Dockerfile new file mode 100644 index 0000000..fe6eeb6 --- /dev/null +++ b/jicofo/Dockerfile @@ -0,0 +1,11 @@ +FROM jitsi/base-java + +RUN \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y jicofo && \ + apt-cleanup + +COPY rootfs/ / + +VOLUME /config + diff --git a/jicofo/Makefile b/jicofo/Makefile new file mode 100644 index 0000000..9a74a73 --- /dev/null +++ b/jicofo/Makefile @@ -0,0 +1,4 @@ +build: + docker build -t jitsi/jicofo . + +.PHONY: build diff --git a/jicofo/rootfs/defaults/sip-communicator.properties b/jicofo/rootfs/defaults/sip-communicator.properties new file mode 100644 index 0000000..986ce83 --- /dev/null +++ b/jicofo/rootfs/defaults/sip-communicator.properties @@ -0,0 +1 @@ +org.jitsi.jicofo.ALWAYS_TRUST_MODE_ENABLED=true 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..96baa86 --- /dev/null +++ b/jicofo/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,6 @@ +#!/usr/bin/with-contenv bash + +if [[ ! -f /config/sip-communicator.properties ]]; then + cp /defaults/sip-communicator.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..0d3700d --- /dev/null +++ b/jicofo/rootfs/etc/services.d/jicofo/run @@ -0,0 +1,9 @@ +#!/usr/bin/with-contenv bash + +JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/ -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=config" +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="auth.$XMPP_DOMAIN" --user_password=$JICOFO_AUTH_PASSWORD" + +exec s6-setuidgid jicofo /bin/bash -c "cd $DAEMON_DIR; JAVA_SYS_PROPS=\"$JAVA_SYS_PROPS\" exec $DAEMON $DAEMON_OPTS" + diff --git a/jvb/Dockerfile b/jvb/Dockerfile new file mode 100644 index 0000000..9947b6e --- /dev/null +++ b/jvb/Dockerfile @@ -0,0 +1,12 @@ +FROM jitsi/base-java + +RUN \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y jitsi-videobridge && \ + apt-cleanup + +COPY rootfs/ / + +VOLUME /config + +EXPOSE 10000/udp 4443 diff --git a/jvb/Makefile b/jvb/Makefile new file mode 100644 index 0000000..470740b --- /dev/null +++ b/jvb/Makefile @@ -0,0 +1,4 @@ +build: + docker build -t jitsi/jvb . + +.PHONY: build 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..b4f816e --- /dev/null +++ b/jvb/rootfs/defaults/sip-communicator.properties @@ -0,0 +1,3 @@ +org.jitsi.videobridge.AUTHORIZED_SOURCE_REGEXP=${JICOFO_AUTH_USER}@auth.${XMPP_DOMAIN}/.* +org.jitsi.videobridge.TCP_HARVESTER_PORT=4443 +org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=${JVB_STUN_SERVERS} 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..3bc5183 --- /dev/null +++ b/jvb/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,15 @@ +#!/usr/bin/with-contenv bash + +if [[ ! -f /config/sip-communicator.properties ]]; then + cp /defaults/sip-communicator.properties /config + sed -i \ + -e "s,\${XMPP_DOMAIN},$XMPP_DOMAIN,g" \ + -e "s,\${JICOFO_AUTH_USER},$JICOFO_AUTH_USER,g" \ + -e "s#\${JVB_STUN_SERVERS}#$JVB_STUN_SERVERS#g" \ + /config/sip-communicator.properties +fi + +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..9a04078 --- /dev/null +++ b/jvb/rootfs/etc/services.d/jvb/run @@ -0,0 +1,8 @@ +#!/usr/bin/with-contenv bash + +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" +DAEMON=/usr/share/jitsi-videobridge/jvb.sh +DAEMON_OPTS="--domain=$XMPP_DOMAIN --host=$XMPP_SERVER --port=5347 --secret=$JVB_COMPONENT_SECRET" + +exec s6-setuidgid jvb /bin/bash -c "JAVA_SYS_PROPS=\"$JAVA_SYS_PROPS\" exec $DAEMON $DAEMON_OPTS" + diff --git a/prosody/Dockerfile b/prosody/Dockerfile new file mode 100644 index 0000000..63f8633 --- /dev/null +++ b/prosody/Dockerfile @@ -0,0 +1,15 @@ +FROM jitsi/base + +RUN \ + echo "deb http://ftp.debian.org/debian stretch-backports main" > /etc/apt/sources.list.d/backports.list && \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -t stretch-backports -y prosody && \ + apt-cleanup && \ + rm -rf /etc/prosody + +COPY rootfs/ / + +EXPOSE 5222 5269 5347 5280 5281 + +VOLUME /config + diff --git a/prosody/Makefile b/prosody/Makefile new file mode 100644 index 0000000..2eb4a64 --- /dev/null +++ b/prosody/Makefile @@ -0,0 +1,4 @@ +build: + docker build -t jitsi/prosody . + +.PHONY: build 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..ccb7e34 --- /dev/null +++ b/prosody/rootfs/defaults/conf.d/jitsi-meet.cfg.lua @@ -0,0 +1,32 @@ +admins = { "focus@auth.${XMPP_DOMAIN}" } + +VirtualHost "${XMPP_DOMAIN}" + authentication = "anonymous" + ssl = { + key = "/config/certs/${XMPP_DOMAIN}.key"; + certificate = "/config/certs/${XMPP_DOMAIN}.crt"; + } + modules_enabled = { + "bosh"; + "pubsub"; + "ping"; + } + + c2s_require_encryption = false + +VirtualHost "auth.${XMPP_DOMAIN}" + ssl = { + key = "/config/certs/auth.${XMPP_DOMAIN}.key"; + certificate = "/config/certs/auth.${XMPP_DOMAIN}.crt"; + } + authentication = "internal_plain" + +Component "conference.${XMPP_DOMAIN}" "muc" + storage = "null" + +Component "jitsi-videobridge.${XMPP_DOMAIN}" + component_secret = "${JVB_COMPONENT_SECRET}" + +Component "focus.${XMPP_DOMAIN}" + component_secret = "${JICOFO_COMPONENT_SECRET}" + diff --git a/prosody/rootfs/defaults/prosody.cfg.lua b/prosody/rootfs/defaults/prosody.cfg.lua new file mode 100644 index 0000000..748f155 --- /dev/null +++ b/prosody/rootfs/defaults/prosody.cfg.lua @@ -0,0 +1,151 @@ +-- 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. +}; + +-- 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; + +pidfile = "/config/data/prosody.pid"; + +-- 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_plain" + +-- 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 = "info"}, to = "console"}; +} + +component_interface = { "*" } + +data_path = "/config/data" + +Include "conf.d/*.cfg.lua" diff --git a/prosody/rootfs/etc/cont-init.d/10-config b/prosody/rootfs/etc/cont-init.d/10-config new file mode 100644 index 0000000..fd6cfc0 --- /dev/null +++ b/prosody/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,35 @@ +#!/usr/bin/with-contenv bash + +AUTH_XMPP_DOMAIN="auth.$XMPP_DOMAIN" +PROSODY_CFG="/config/prosody.cfg.lua" + +if [[ ! -d /config/data ]]; then + mkdir -p /config/data + chmod 777 /config/data +fi + +if [[ ! -f $PROSODY_CFG ]]; then + cp -r /defaults/* /config + sed -i \ + -e "s,\${XMPP_DOMAIN},$XMPP_DOMAIN,g" \ + -e "s,\${JICOFO_COMPONENT_SECRET},$JICOFO_COMPONENT_SECRET,g" \ + -e "s,\${JVB_COMPONENT_SECRET},$JVB_COMPONENT_SECRET,g" \ + /config/conf.d/jitsi-meet.cfg.lua + prosodyctl --config $PROSODY_CFG register $JICOFO_AUTH_USER $AUTH_XMPP_DOMAIN $JICOFO_AUTH_PASSWORD +fi + +mkdir /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/$AUTH_XMPP_DOMAIN.crt ]]; then + # echo for using all default values + echo | prosodyctl --config $PROSODY_CFG cert generate $AUTH_XMPP_DOMAIN +fi + +# certs vill be created in /var/lib/prosody +mv /var/lib/prosody/*.{crt,key} /config/certs/ + diff --git a/prosody/rootfs/etc/services.d/prosody/run b/prosody/rootfs/etc/services.d/prosody/run new file mode 100644 index 0000000..e1e3ab6 --- /dev/null +++ b/prosody/rootfs/etc/services.d/prosody/run @@ -0,0 +1,3 @@ +#!/usr/bin/with-contenv bash +exec s6-setuidgid prosody prosody --config /config/prosody.cfg.lua + diff --git a/web/Dockerfile b/web/Dockerfile new file mode 100644 index 0000000..87c0a26 --- /dev/null +++ b/web/Dockerfile @@ -0,0 +1,14 @@ +FROM jitsi/base + +RUN \ + apt-dpkg-wrap apt-get update && \ + apt-dpkg-wrap apt-get install -y nginx-extras jitsi-meet-web && \ + apt-cleanup && \ + rm -f /etc/nginx/conf.d/default.conf + +COPY rootfs/ / + +EXPOSE 80 443 + +VOLUME /config + diff --git a/web/Makefile b/web/Makefile new file mode 100644 index 0000000..7424e24 --- /dev/null +++ b/web/Makefile @@ -0,0 +1,4 @@ +build: + docker build -t jitsi/web . + +.PHONY: build diff --git a/web/rootfs/defaults/config.js b/web/rootfs/defaults/config.js new file mode 100644 index 0000000..0e84042 --- /dev/null +++ b/web/rootfs/defaults/config.js @@ -0,0 +1,388 @@ +/* eslint-disable no-unused-vars, no-var */ + +var config = { + // Configuration + // + + // Alternative location for the configuration. + // configLocation: './config.json', + + // Custom function which given the URL path should return a room name. + // getroomnode: function (path) { return 'someprefixpossiblybasedonpath'; }, + + + // Connection + // + + hosts: { + // XMPP domain. + domain: 'jitsi-meet.example.com', + + // XMPP MUC domain. FIXME: use XEP-0030 to discover it. + muc: 'conference.jitsi-meet.example.com' + + // When using authentication, domain for guest users. + // anonymousdomain: 'guest.example.com', + + // Domain for authenticated users. Defaults to . + // authdomain: 'jitsi-meet.example.com', + + // Jirecon recording component domain. + // jirecon: 'jirecon.jitsi-meet.example.com', + + // Call control component (Jigasi). + // call_control: 'callcontrol.jitsi-meet.example.com', + + // Focus component domain. Defaults to focus.. + // focus: 'focus.jitsi-meet.example.com', + }, + + // BOSH URL. FIXME: use XEP-0156 to discover it. + bosh: '/http-bind', + + // The name of client node advertised in XEP-0115 'c' stanza + clientNode: 'http://jitsi.org/jitsimeet', + + // The real JID of focus participant - can be overridden here + // focusUserJid: 'focus@auth.jitsi-meet.example.com', + + + // Testing / experimental features. + // + + testing: { + // Enables experimental simulcast support on Firefox. + enableFirefoxSimulcast: false, + + // P2P test mode disables automatic switching to P2P when there are 2 + // participants in the conference. + p2pTestMode: false + }, + + // Disables ICE/UDP by filtering out local and remote UDP candidates in + // signalling. + // webrtcIceUdpDisable: false, + + // Disables ICE/TCP by filtering out local and remote TCP candidates in + // signalling. + // webrtcIceTcpDisable: false, + + + // Media + // + + // Audio + + // Disable measuring of audio levels. + // disableAudioLevels: false, + + // Start the conference in audio only mode (no video is being received nor + // sent). + // startAudioOnly: false, + + // Every participant after the Nth will start audio muted. + // startAudioMuted: 10, + + // Start calls with audio muted. Unlike the option above, this one is only + // applied locally. FIXME: having these 2 options is confusing. + // startWithAudioMuted: false, + + // Video + + // Sets the preferred resolution (height) for local video. Defaults to 720. + // resolution: 720, + + // w3c spec-compliant video constraints to use for video capture. Currently + // used by browsers that return true from lib-jitsi-meet's + // util#browser#usesNewGumFlow. The constraints are independency from + // this config's resolution value. Defaults to requesting an ideal aspect + // ratio of 16:9 with an ideal resolution of 1080p. + // constraints: { + // video: { + // aspectRatio: 16 / 9, + // height: { + // ideal: 1080, + // max: 1080, + // min: 240 + // } + // } + // }, + + // Enable / disable simulcast support. + // disableSimulcast: false, + + // Suspend sending video if bandwidth estimation is too low. This may cause + // problems with audio playback. Disabled until these are fixed. + disableSuspendVideo: true, + + // Every participant after the Nth will start video muted. + // startVideoMuted: 10, + + // Start calls with video muted. Unlike the option above, this one is only + // applied locally. FIXME: having these 2 options is confusing. + // startWithVideoMuted: false, + + // If set to true, prefer to use the H.264 video codec (if supported). + // Note that it's not recommended to do this because simulcast is not + // supported when using H.264. For 1-to-1 calls this setting is enabled by + // default and can be toggled in the p2p section. + // preferH264: true, + + // If set to true, disable H.264 video codec by stripping it out of the + // SDP. + // disableH264: false, + + // Desktop sharing + + // Enable / disable desktop sharing + // disableDesktopSharing: false, + + // The ID of the jidesha extension for Chrome. + desktopSharingChromeExtId: null, + + // Whether desktop sharing should be disabled on Chrome. + desktopSharingChromeDisabled: true, + + // The media sources to use when using screen sharing with the Chrome + // extension. + desktopSharingChromeSources: [ 'screen', 'window', 'tab' ], + + // Required version of Chrome extension + desktopSharingChromeMinExtVersion: '0.1', + + // The ID of the jidesha extension for Firefox. If null, we assume that no + // extension is required. + desktopSharingFirefoxExtId: null, + + // Whether desktop sharing should be disabled on Firefox. + desktopSharingFirefoxDisabled: false, + + // The maximum version of Firefox which requires a jidesha extension. + // Example: if set to 41, we will require the extension for Firefox versions + // up to and including 41. On Firefox 42 and higher, we will run without the + // extension. + // If set to -1, an extension will be required for all versions of Firefox. + desktopSharingFirefoxMaxVersionExtRequired: 51, + + // The URL to the Firefox extension for desktop sharing. + desktopSharingFirefoxExtensionURL: null, + + // Optional desktop sharing frame rate options. Default value: min:5, max:5. + // desktopSharingFrameRate: { + // min: 5, + // max: 5 + // }, + + // Try to start calls with screen-sharing instead of camera video. + // startScreenSharing: false, + + // Recording + + // Whether to enable recording or not. + // enableRecording: false, + + // Type for recording: one of jibri or jirecon. + // recordingType: 'jibri', + + // Misc + + // Default value for the channel "last N" attribute. -1 for unlimited. + channelLastN: -1, + + // Disables or enables RTX (RFC 4588) (defaults to false). + // disableRtx: false, + + // Use XEP-0215 to fetch STUN and TURN servers. + // useStunTurn: true, + + // Enable IPv6 support. + // useIPv6: true, + + // Enables / disables a data communication channel with the Videobridge. + // Values can be 'datachannel', 'websocket', true (treat it as + // 'datachannel'), undefined (treat it as 'datachannel') and false (don't + // open any channel). + // openBridgeChannel: true, + + + // UI + // + + // Use display name as XMPP nickname. + // useNicks: false, + + // Require users to always specify a display name. + // requireDisplayName: true, + + // Whether to use a welcome page or not. In case it's false a random room + // will be joined when no room is specified. + enableWelcomePage: true, + + // Enabling the close page will ignore the welcome page redirection when + // a call is hangup. + // enableClosePage: false, + + // Disable hiding of remote thumbnails when in a 1-on-1 conference call. + // disable1On1Mode: false, + + // The minimum value a video's height (or width, whichever is smaller) needs + // to be in order to be considered high-definition. + minHDHeight: 540, + + // Default language for the user interface. + // defaultLanguage: 'en', + + // If true all users without a token will be considered guests and all users + // with token will be considered non-guests. Only guests will be allowed to + // edit their profile. + enableUserRolesBasedOnToken: false, + + // Message to show the users. Example: 'The service will be down for + // maintenance at 01:00 AM GMT, + // noticeMessage: '', + + + // Stats + // + + // Whether to enable stats collection or not in the TraceablePeerConnection. + // This can be useful for debugging purposes (post-processing/analysis of + // the webrtc stats) as it is done in the jitsi-meet-torture bandwidth + // estimation tests. + // gatherStats: false, + + // To enable sending statistics to callstats.io you must provide the + // Application ID and Secret. + // callStatsID: '', + // callStatsSecret: '', + + // enables callstatsUsername to be reported as statsId and used + // by callstats as repoted remote id + // enableStatsID: false + + // enables sending participants display name to callstats + // enableDisplayNameInStats: false + + + // Privacy + // + + // If third party requests are disabled, no other server will be contacted. + // This means avatars will be locally generated and callstats integration + // will not function. + // disableThirdPartyRequests: false, + + + // Peer-To-Peer mode: used (if enabled) when there are just 2 participants. + // + + p2p: { + // Enables peer to peer mode. When enabled the system will try to + // establish a direct connection when there are exactly 2 participants + // in the room. If that succeeds the conference will stop sending data + // through the JVB and use the peer to peer connection instead. When a + // 3rd participant joins the conference will be moved back to the JVB + // connection. + enabled: true, + + // Use XEP-0215 to fetch STUN and TURN servers. + // useStunTurn: true, + + // The STUN servers that will be used in the peer to peer connections + stunServers: [ + { urls: 'stun:stun.l.google.com:19302' }, + { urls: 'stun:stun1.l.google.com:19302' }, + { urls: 'stun:stun2.l.google.com:19302' } + ], + + // Sets the ICE transport policy for the p2p connection. At the time + // of this writing the list of possible values are 'all' and 'relay', + // but that is subject to change in the future. The enum is defined in + // the WebRTC standard: + // https://www.w3.org/TR/webrtc/#rtcicetransportpolicy-enum. + // If not set, the effective value is 'all'. + // iceTransportPolicy: 'all', + + // If set to true, it will prefer to use H.264 for P2P calls (if H.264 + // is supported). + preferH264: true + + // If set to true, disable H.264 video codec by stripping it out of the + // SDP. + // disableH264: false, + + // How long we're going to wait, before going back to P2P after the 3rd + // participant has left the conference (to filter out page reload). + // backToP2PDelay: 5 + }, + + // A list of scripts to load as lib-jitsi-meet "analytics handlers". + // analyticsScriptUrls: [ + // "libs/analytics-ga.js", // google-analytics + // "https://example.com/my-custom-analytics.js" + // ], + + // The Google Analytics Tracking ID + // googleAnalyticsTrackingId = 'your-tracking-id-here-UA-123456-1', + + // Information about the jitsi-meet instance we are connecting to, including + // the user region as seen by the server. + deploymentInfo: { + // shard: "shard1", + // region: "europe", + // userRegion: "asia" + } + + + // List of undocumented settings used in jitsi-meet + /** + alwaysVisibleToolbar + autoEnableDesktopSharing + autoRecord + autoRecordToken + debug + debugAudioLevels + deploymentInfo + dialInConfCodeUrl + dialInNumbersUrl + dialOutAuthUrl + dialOutCodesUrl + disableRemoteControl + displayJids + enableLocalVideoFlip + etherpad_base + externalConnectUrl + firefox_fake_device + iAmRecorder + iAmSipGateway + peopleSearchQueryTypes + peopleSearchUrl + requireDisplayName + tokenAuthUrl + */ + + // List of undocumented settings used in lib-jitsi-meet + /** + _peerConnStatusOutOfLastNTimeout + _peerConnStatusRtcMuteTimeout + abTesting + avgRtpStatsN + callStatsConfIDNamespace + callStatsCustomScriptUrl + desktopSharingSources + disableAEC + disableAGC + disableAP + disableHPF + disableNS + enableLipSync + enableTalkWhileMuted + forceJVB121Ratio + hiddenDomain + ignoreStartMuted + nick + startBitrate + */ +}; + +/* eslint-enable no-unused-vars, no-var */ diff --git a/web/rootfs/defaults/default b/web/rootfs/defaults/default new file mode 100644 index 0000000..5aca755 --- /dev/null +++ b/web/rootfs/defaults/default @@ -0,0 +1,34 @@ +server { + listen 80 default_server; + listen 443 ssl; + + ssl_certificate /config/keys/cert.crt; + ssl_certificate_key /config/keys/cert.key; + + server_name _; + + client_max_body_size 0; + + root /usr/share/jitsi-meet; + index index.html + error_page 404 /static/404.html; + + location ~ ^/([a-zA-Z0-9=\?]+)$ { + rewrite ^/(.*)$ / break; + } + + location /config.js { + alias /config/config.js; + } + + location / { + ssi on; + } + + # BOSH + location /http-bind { + proxy_pass ${XMPP_BOSH_URL_BASE}/http-bind; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host ${XMPP_DOMAIN}; + } +} diff --git a/web/rootfs/defaults/nginx.conf b/web/rootfs/defaults/nginx.conf new file mode 100644 index 0000000..fa1a78e --- /dev/null +++ b/web/rootfs/defaults/nginx.conf @@ -0,0 +1,60 @@ +user www-data; +worker_processes 4; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + client_max_body_size 0; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # Logging Settings + ## + + access_log /dev/stdout; + error_log /dev/stderr; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + include /config/nginx/site-confs/*; +} + + +daemon off; 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..cb88cc8 --- /dev/null +++ b/web/rootfs/etc/cont-init.d/10-config @@ -0,0 +1,26 @@ +#!/usr/bin/with-contenv bash + +# make our folders +mkdir -p \ + /config/{nginx/site-confs,keys} \ + /run \ + /var/lib/nginx/tmp/client_body \ + /var/tmp/nginx + +# copy config files +if [[ ! -f /config/nginx/nginx.conf ]]; then + cp /defaults/nginx.conf /config/nginx/nginx.conf +fi + +if [[ ! -f /config/nginx/site-confs/default ]]; then + cp /defaults/default /config/nginx/site-confs/default + sed -i \ + -e "s,\${XMPP_DOMAIN},$XMPP_DOMAIN,g" \ + -e "s,\${XMPP_BOSH_URL_BASE},$XMPP_BOSH_URL_BASE,g" \ + /config/nginx/site-confs/default +fi + +if [[ ! -f /config/config.js ]]; then + cp /defaults/config.js /config/config.js + sed -i "s/jitsi-meet.example.com/$XMPP_DOMAIN/g" /config/config.js +fi diff --git a/web/rootfs/etc/cont-init.d/20-keygen b/web/rootfs/etc/cont-init.d/20-keygen new file mode 100644 index 0000000..f63c30e --- /dev/null +++ b/web/rootfs/etc/cont-init.d/20-keygen @@ -0,0 +1,10 @@ +#!/usr/bin/with-contenv bash + +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 + diff --git a/web/rootfs/etc/services.d/nginx/run b/web/rootfs/etc/services.d/nginx/run new file mode 100644 index 0000000..bb0dc1d --- /dev/null +++ b/web/rootfs/etc/services.d/nginx/run @@ -0,0 +1,3 @@ +#!/usr/bin/with-contenv bash +nginx -c /config/nginx/nginx.conf +