commit c11d15be4738caead7791c43d090c32a0dc7f045 Author: Knut Ahlers Date: Thu Mar 19 01:38:59 2020 +0100 Initial version diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f1a7433 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM debian:stable + +ENV DEBIAN_FRONTEND=noninteractive \ + GOSU_VERSION=1.11 \ + KORVIKE_VERSION=v0.6.1 \ + S6_VERSION=v1.21.8.0 \ + TERM=xterm + +COPY build.sh /usr/local/bin/ + +RUN set -ex \ + && bash /usr/local/bin/build.sh + +# Add config templates +COPY config/* /usr/local/share/jitsi-config/ + +# Add S6 start files +COPY setup.sh /etc/cont-init.d/ +COPY services /etc/services.d + +# Application expose +EXPOSE 80/tcp + +# Hopefully has some sense? +EXPOSE 10000/udp 10001/udp 10002/udp 10003/udp 10004/udp 10005/udp 10006/udp 10007/udp 10008/udp 10009/udp 10010/udp + +ENTRYPOINT ["/init"] diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..7759459 --- /dev/null +++ b/build.sh @@ -0,0 +1,61 @@ +#!/bin/bash +set -euxo pipefail + +packages_build=( + curl + gnupg +) + +packages_install=( + jitsi-meet +) + +no_postinst_pkgs=( + jitsi-meet-prosody # Executes some certificate generator on wrong hostname + jitsi-meet-web-config # Executes another cert generator +) + +# Install packages required for build +apt-get update +apt-get install -yq "${packages_build[@]}" + +# Add Jitsi install repo +echo "deb https://download.jitsi.org stable/" >>/etc/apt/sources.list.d/jitsi.list +curl -sSfL "https://download.jitsi.org/jitsi-key.gpg.key" | apt-key add - +apt-get update + +# Install jitsi-meet without triggering postinst which breaks in Docker build +pushd /tmp +for pkg in "${no_postinst_pkgs[@]}"; do + # Get and unpack package + apt-get download ${pkg} + dpkg --unpack ${pkg}*.deb + + # Remove postinst file in case it exists + rm -f /var/lib/dpkg/info/${pkg}.postinst + + # Install package + dpkg --configure ${pkg} || apt-get install -yqf #To fix dependencies +done +popd + +apt-get install -yq "${packages_install[@]}" + +# Install korvike in the container +curl -sSfL "https://github.com/Luzifer/korvike/releases/download/${KORVIKE_VERSION}/korvike_linux_amd64.tar.gz" | + tar -xzf - -C /usr/local/bin +mv /usr/local/bin/korvike_linux_amd64 /usr/local/bin/korvike + +# Install gosu +curl -sSfLo /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64" +chmod 0755 /usr/local/bin/gosu + +# Install S6 overlay +curl -sSfL "https://github.com/just-containers/s6-overlay/releases/download/${S6_VERSION}/s6-overlay-amd64.tar.gz" | + tar -xzf - -C / + +# Cleanup +apt-get remove -yq --purge "${packages_build[@]}" +apt-get autoremove -yq --purge +apt-get clean +rm -rf /var/lib/apt/lists/* || true diff --git a/config/jitsi-meet.js b/config/jitsi-meet.js new file mode 100644 index 0000000..b0bb257 --- /dev/null +++ b/config/jitsi-meet.js @@ -0,0 +1,9 @@ +var config = { + hosts: { + domain: '{{ env `JITSI_DOMAIN` }}', + muc: 'conference.{{ env `JITSI_DOMAIN` }}', + bridge: 'jitsi-videobridge.{{ env `JITSI_DOMAIN` }}', + }, + useNicks: false, + bosh: '//{{ env `JITSI_DOMAIN` }}/http-bind', +}; diff --git a/config/nginx.conf b/config/nginx.conf new file mode 100644 index 0000000..094225a --- /dev/null +++ b/config/nginx.conf @@ -0,0 +1,73 @@ +user www-data; +worker_processes 1; + +error_log /var/log/nginx/error.log; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; + # multi_accept on; +} + +http { + include /etc/nginx/mime.types; + + access_log /var/log/nginx/access.log; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 65; + tcp_nodelay on; + + tcp_nopush on; + types_hash_max_size 2048; + server_names_hash_bucket_size 64; + + gzip on; + gzip_disable "MSIE [1-6]\.(?!.*SV1)"; + + include /etc/nginx/conf.d/*.conf; + + server { + listen 80 default_server; + + server_name localhost; + + root /usr/share/jitsi-meet; + ssi on; + index index.html index.htm; + error_page 404 /static/404.html; + + location = /config.js { + alias /etc/jitsi/meet/config.js; + } + + location = /external_api.js { + alias /usr/share/jitsi-meet/libs/external_api.min.js; + } + + #ensure all static content can always be found first + location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$ { + add_header 'Access-Control-Allow-Origin' '*'; + alias /usr/share/jitsi-meet/$1/$2; + } + + # BOSH + location = /http-bind { + proxy_pass http://localhost:5280/http-bind; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $http_host; + } + + location ~ ^/([^/?&:'"]+)$ { + try_files $uri @root_path; + } + + location @root_path { + rewrite ^/(.*)$ / break; + } + + } +} diff --git a/config/prosody.cfg.lua b/config/prosody.cfg.lua new file mode 100644 index 0000000..cf4a52e --- /dev/null +++ b/config/prosody.cfg.lua @@ -0,0 +1,32 @@ +VirtualHost "{{ env `JITSI_DOMAIN` }}" + authentication = "anonymous" + + ssl = { + key = "/var/lib/prosody/{{ env `JITSI_DOMAIN` }}.key"; + certificate = "/var/lib/prosody/{{ env `JITSI_DOMAIN` }}.crt"; + } + + modules_enabled = { + "bosh"; + "pubsub"; + } + + c2s_require_encryption = false + +VirtualHost "auth.{{ env `JITSI_DOMAIN` }}" + ssl = { + key = "/var/lib/prosody/auth.{{ env `JITSI_DOMAIN` }}.key"; + certificate = "/var/lib/prosody/auth.{{ env `JITSI_DOMAIN` }}.crt"; + } + + authentication = "internal_plain" + +admins = { "focus@auth.{{ env `JITSI_DOMAIN` }}" } + +Component "conference.{{ env `JITSI_DOMAIN` }}" "muc" + +Component "jitsi-videobridge.{{ env `JITSI_DOMAIN` }}" + component_secret = "{{ env `JITSI_VBR_SECRET` }}" + +Component "focus.{{ env `JITSI_DOMAIN` }}" + component_secret = "{{ env `JITSI_JICOFO_SECRET` }}" diff --git a/config/startenv b/config/startenv new file mode 100644 index 0000000..7aa188a --- /dev/null +++ b/config/startenv @@ -0,0 +1,12 @@ +JICOFO_HOST=localhost +JICOFO_HOSTNAME={{ env `JITSI_DOMAIN` }} +JICOFO_SECRET={{ env `JITSI_JICOFO_SECRET` }} +JICOFO_AUTH_USER=focus +JICOFO_AUTH_DOMAIN=auth.{{ env `JITSI_DOMAIN` }} +JICOFO_AUTH_PASSWORD={{ env `JITSI_ADMIN_SECRET` }} + + +JVB_HOST=localhost +JVB_HOSTNAME={{ env `JITSI_DOMAIN` }} +JVB_PORT=5347 +JVB_SECRET={{ env `JITSI_VBR_SECRET` }} diff --git a/services/jicofo/run b/services/jicofo/run new file mode 100755 index 0000000..0127f04 --- /dev/null +++ b/services/jicofo/run @@ -0,0 +1,12 @@ +#!/bin/bash +set -euxo pipefail + +[ -f /etc/jitsi-env.conf ] && source /etc/jitsi-env.conf + +exec /usr/local/bin/gosu jicofo /usr/share/jicofo/jicofo.sh \ + --host=$JICOFO_HOST \ + --domain=$JICOFO_HOSTNAME \ + --secret=$JICOFO_SECRET \ + --user_name=$JICOFO_AUTH_USER \ + --user_domain=$JICOFO_AUTH_DOMAIN \ + --user_password=$JICOFO_AUTH_PASSWORD diff --git a/services/nginx/run b/services/nginx/run new file mode 100755 index 0000000..503eb56 --- /dev/null +++ b/services/nginx/run @@ -0,0 +1,2 @@ +#!/usr/bin/execlineb -P +nginx -g "daemon off;" diff --git a/services/prosody/run b/services/prosody/run new file mode 100755 index 0000000..aacc5a6 --- /dev/null +++ b/services/prosody/run @@ -0,0 +1,12 @@ +#!/bin/bash +set -euxo pipefail + +DAEMON=/usr/bin/prosody +PIDPATH=/run/prosody +PIDFILE="$PIDPATH"/prosody.pid +USER=prosody + +mkdir -p "$(dirname $PIDFILE)" +chown prosody:adm "$(dirname $PIDFILE)" + +exec /usr/local/bin/gosu prosody /usr/bin/prosody diff --git a/services/videobridge/run b/services/videobridge/run new file mode 100755 index 0000000..196b3be --- /dev/null +++ b/services/videobridge/run @@ -0,0 +1,10 @@ +#!/bin/bash +set -euxo pipefail + +[ -f /etc/jitsi-env.conf ] && source /etc/jitsi-env.conf + +exec /usr/local/bin/gosu jvb /usr/share/jitsi-videobridge/jvb.sh \ + --host=$JVB_HOST \ + --domain=$JVB_HOSTNAME \ + --port=$JVB_PORT \ + --secret=$JVB_SECRET diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000..769ee7b --- /dev/null +++ b/setup.sh @@ -0,0 +1,42 @@ +#!/usr/bin/with-contenv /bin/bash +set -euxo pipefail + +cfg_file_path="/usr/local/share/jitsi-config" + +[ -n "${JITSI_DOMAIN:-}" ] || { + echo "Missing JITSI_DOMAIN env variable" >&2 + exit 1 +} + +# Generate internal passwords +export JITSI_VBR_SECRET=$(openssl rand -hex 20) +export JITSI_JICOFO_SECRET=$(openssl rand -hex 20) +export JITSI_ADMIN_SECRET=$(openssl rand -hex 20) + +# Generate configuration files +korvike \ + -i "${cfg_file_path}/jitsi-meet.js" \ + -o "/etc/jitsi/meet/config.js" + +korvike \ + -i "${cfg_file_path}/prosody.cfg.lua" \ + -o "/etc/prosody/conf.d/${JITSI_DOMAIN}.cfg.lua" + +korvike \ + -i "${cfg_file_path}/nginx.conf" \ + -o "/etc/nginx/nginx.conf" + +korvike \ + -i "${cfg_file_path}/startenv" \ + -o "/etc/jitsi-env.conf" + +# Generate certificates +echo | prosodyctl cert generate "${JITSI_DOMAIN}" +echo | prosodyctl cert generate "auth.${JITSI_DOMAIN}" + +# Trust generated certificate +ln -sf /var/lib/prosody/auth.${JITSI_DOMAIN}.crt /usr/local/share/ca-certificates/auth.${JITSI_DOMAIN}.crt +update-ca-certificates -f + +# Generate user for admin +prosodyctl register focus "auth.${JITSI_DOMAIN}" "${JITSI_ADMIN_SECRET}"