diff --git a/.env.sample b/.env.sample index 840dfd1..2101f2c 100644 --- a/.env.sample +++ b/.env.sample @@ -5,3 +5,15 @@ DOMAIN=snikket.example.com LETS_ENCRYPT_ENV=production SNIKKET_ADMIN_EMAIL=contact@snikket.example.com + +# for sharing traefik generated certificates with snikket +# "abra app volume ls " should give you this name +TRAEFIK_SERVICE=my_traefik_service_certs_volume + +COMPOSE_FILE="compose.yml" + +SECRET_COTURN_SECRET_VERSION=v1 +SNIKKET_TWEAK_TURNSERVER_DOMAIN=coturn.example.com + +# internal coturn +#COMPOSE_FILE="compose.yml:compose.coturn-int.yml" diff --git a/README.md b/README.md index 88e40b4..7dbea1d 100644 --- a/README.md +++ b/README.md @@ -15,18 +15,46 @@ Chat that is simple, secure, and private. -## Create admin invite +## Tricks & Tips + +### Post-deploy steps + +The `certs` service needs to copy over the right certificates from traefik. If +you're deploying for the first time, then this could take a minute. Once the certs +are copied over, you'll have to manually restart the app service. + +``` +abra app logs certs +abra app run server ls -lha /certs +abra app restsart app +``` + +### DNS requirements + +You need 3 A records, pointing to the same IP. + +- **chat.foo.com**: main web log in +- **share.chat.foo.com**: file upload +- **groups.chat.foo.com**: muc support + +### Create admin invite ``` abra app run server create-invite --admin --group default ``` -## Fix broken initialisation +### How does the coturn setup work? -Until [`#1`](https://git.coopcloud.tech/coop-cloud/snikket/issues/1) is fixed... +We default to external using a default coturn to support the homebrew server as +a first class citizen. Coturn is known to not work at all if behind a NAT and +is better served directlry from a ipv4. For homebrew setups (behind router), +it's better to dial out to an external coturn server. + +If you want to use the internal Snikket coturn setup, use the following: ``` -abra app run server sh -c "chown -R prosody:prosody /certs/*" -abra app restart app -abra app restart server +COMPOSE_FILE="compose.yml:compose.coturn-int.yml" ``` + +There are issues with exposing the required amount of ports, please see +[`#5`](https://git.coopcloud.tech/coop-cloud/snikket/issues/5). diff --git a/abra.sh b/abra.sh new file mode 100644 index 0000000..7c5fe57 --- /dev/null +++ b/abra.sh @@ -0,0 +1 @@ +export APP_ENTRYPOINT_VERSION=v1 diff --git a/compose.coturn-int.yml b/compose.coturn-int.yml new file mode 100644 index 0000000..86bba3c --- /dev/null +++ b/compose.coturn-int.yml @@ -0,0 +1,69 @@ +--- +version: "3.8" + +services: + server: + ports: + # Audio/Video Data Proxy Negotiation and IP discovery (STUN/TURN) + - target: 3478 + published: 3478 + mode: host + - target: 3479 + published: 3479 + mode: host + + # Audio/Video Data Proxy Negotiations and IP Discovery over TLS (STUN/TURN over TLS) + - target: 5439 + published: 5439 + protocol: tcp + mode: host + - target: 5439 + published: 5439 + protocol: udp + mode: host + - target: 5350 + published: 5350 + protocol: tcp + mode: host + - target: 5350 + published: 5350 + protocol: udp + mode: host + + # Audio/Video Data Proxy (Turn Data, see below) + - target: 49152 + published: 49152 + protocol: udp + mode: host + - target: 49153 + published: 49153 + protocol: udp + mode: host + - target: 49154 + published: 49154 + protocol: udp + mode: host + - target: 49155 + published: 49155 + protocol: udp + mode: host + - target: 49156 + published: 49156 + protocol: udp + mode: host + - target: 49157 + published: 49157 + protocol: udp + mode: host + - target: 49158 + published: 49158 + protocol: udp + mode: host + - target: 49159 + published: 49159 + protocol: udp + mode: host + - target: 49160 + published: 49160 + protocol: udp + mode: host diff --git a/compose.yml b/compose.yml index eeb501d..fa2b7c0 100644 --- a/compose.yml +++ b/compose.yml @@ -3,15 +3,16 @@ version: "3.8" x-environment: &default-env - SNIKKET_ADMIN_EMAIL - - SNIKKET_CERTFILE=/certs/$DOMAIN/certificate.crt + - SNIKKET_CERTFILE=/certs/$DOMAIN/cert.pem - SNIKKET_DOMAIN=${DOMAIN} - - SNIKKET_KEYFILE=/certs/$DOMAIN/privatekey.key + - SNIKKET_KEYFILE=/certs/$DOMAIN/key.pem - SNIKKET_TWEAK_INTERNAL_HTTP_HOST=${STACK_NAME}_server - SNIKKET_TWEAK_INTERNAL_HTTP_INTERFACE=0.0.0.0 - SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_HOST=${STACK_NAME}_portal - SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE=0.0.0.0 - - SNIKKET_TWEAK_TURNSERVER_MAX_PORT=49153 - - SNIKKET_TWEAK_TURNSERVER_MIN_PORT=49160 + - SNIKKET_TWEAK_TURNSERVER=0 + - SNIKKET_TWEAK_TURNSERVER_DOMAIN + - SNIKKET_TWEAK_TURNSERVER_SECRET_FILE=/run/secrets/coturn_secret - SNIKKET_WEB_PROSODY_ENDPOINT=http://${STACK_NAME}_server:5280 services: @@ -23,9 +24,6 @@ services: environment: *default-env volumes: - snikket_data:/snikket - depends_on: - - snikket_portal - - snikket_server deploy: labels: - "traefik.enable=true" @@ -44,10 +42,17 @@ services: server: image: thecoopcloud/snikket-server:latest + secrets: + - coturn_secret + configs: + - source: app_entrypoint + target: /docker-entrypoint.sh + mode: 0555 volumes: - snikket_data:/snikket - certs:/certs environment: *default-env + entrypoint: /docker-entrypoint.sh networks: - backend ports: @@ -69,85 +74,27 @@ services: published: 5000 mode: host - # Audio/Video Data Proxy Negotiation and IP discovery (STUN/TURN) - - target: 3478 - published: 3478 - mode: host - - target: 3479 - published: 3479 - mode: host - - # Audio/Video Data Proxy Negotiations and IP Discovery over TLS (STUN/TURN over TLS) - - target: 5439 - published: 5439 - protocol: tcp - mode: host - - target: 5439 - published: 5439 - protocol: udp - mode: host - - target: 5350 - published: 5350 - protocol: tcp - mode: host - - target: 5350 - published: 5350 - protocol: udp - mode: host - - # Audio/Video Data Proxy (Turn Data, see below) - - target: 49152 - published: 49152 - protocol: udp - mode: host - - target: 49153 - published: 49153 - protocol: udp - mode: host - - target: 49154 - published: 49154 - protocol: udp - mode: host - - target: 49155 - published: 49155 - protocol: udp - mode: host - - target: 49156 - published: 49156 - protocol: udp - mode: host - - target: 49157 - published: 49157 - protocol: udp - mode: host - - target: 49158 - published: 49158 - protocol: udp - mode: host - - target: 49159 - published: 49159 - protocol: udp - mode: host - - target: 49160 - published: 49160 - protocol: udp - mode: host - - certdumper: - image: ldez/traefik-certs-dumper:v2.7.4 - entrypoint: sh -c ' - apk add jq - ; while ! [ -e /traefik/production-acme.json ] - || ! [ `jq ".production.Certificates | length" /traefik/production-acme.json` != 0 ]; do - sleep 1 - ; done - && traefik-certs-dumper file --watch --source /traefik/production-acme.json - --dest /output --domain-subdir=true --version v2' - environment: - - DOMAIN=${DOMAIN} + certs: + image: humenius/traefik-certs-dumper:1.5 volumes: - - "traefik_letsencrypt:/traefik" - - "certs:/output" + - traefik_letsencrypt:/traefik + - certs:/output + environment: + - ACME_FILE_PATH=/traefik/production-acme.json + - DOMAIN=${DOMAIN},groups.${DOMAIN},share.${DOMAIN} + - OVERRIDE_UID=101 # prosody + - OVERRIDE_GID=102 # prosody + +configs: + app_entrypoint: + name: ${STACK_NAME}_app_entrypoint_${APP_ENTRYPOINT_VERSION} + file: entrypoint.sh.tmpl + template_driver: golang + +secrets: + coturn_secret: + external: true + name: ${STACK_NAME}_coturn_secret_${SECRET_COTURN_SECRET_VERSION} volumes: snikket_data: diff --git a/entrypoint.sh.tmpl b/entrypoint.sh.tmpl new file mode 100644 index 0000000..5ca25d0 --- /dev/null +++ b/entrypoint.sh.tmpl @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + + local val="$def" + + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + + export "$var"="$val" + unset "$fileVar" +} + +file_env "SNIKKET_TWEAK_TURNSERVER_SECRET" + +# upstream entrypoint +# https://github.com/snikket-im/snikket-server/blob/master/Dockerfile +/bin/entrypoint.sh "$@"