------------------------------------------- * **talk-hpb** * **Jonathan Haack** * **Haack's Networking** * **webmaster@haacksnetworking.org** ------------------------------------------- //Talk HPB// ------------------------------------------- ~~NOTOC~~ ==== Introduction ==== This tutorial is for Debian users who want or need to spin up a high performance back-end for Nextcloud Talk. This helps with multi-user calls and/or nasty NAT situations. Here's the layout: ^ Role ^ Bind ^ Public ^ | Signaling | ''127.0.0.1:8088'' → container ''8081'' | ''https://talk.haacksnetworking.org'' (Apache) | | TURN | ''0.0.0.0:3478/tcp'' + ''3478/udp'' | ''talk.haacksnetworking.org:3478'' | We will use the following image: * Image: ''ghcr.io/nextcloud-releases/aio-talk:latest'' This image is basically signaling, NATS, Janus, and eturnal. Let's make sure the host is setup properly. ==== 0. Host firewall (root) ==== We need to open turn on udp 3478 and its fallback, tcp 3478. This helps clients behind nasty NAT. The signaling stays on localhost. Let's open the ports: ufw allow 3478/tcp ufw allow 3478/udp ==== 1. Directories and secrets (worker) ==== mkdir -p ~/talk-hpb umask 077 openssl rand -hex 32 > ~/talk-hpb/signaling.secret openssl rand -hex 32 > ~/talk-hpb/turn.secret openssl rand -hex 32 > ~/talk-hpb/internal.secret Keep these stable for yearly or longer rotations. No need to rotate if no compromise is suspected, etc., and usage is tightly monitored and restricted. ==== 2. Quadlet ==== Create the quadlet for monitoring and starting/stopping the service as the ''worker'' user ''nano ~/.config/containers/systemd/container-talk-hpb.container'' mkdir -p ~/.config/containers/systemd cat > ~/.config/containers/systemd/container-talk-hpb.container << 'EOF' [Container] ContainerName=talk-hpb Image=ghcr.io/nextcloud-releases/aio-talk:latest PublishPort=127.0.0.1:8088:8081 PublishPort=3478:3478/tcp PublishPort=3478:3478/udp Environment=NC_DOMAIN=cloud.haacksnetworking.org Environment=TALK_HOST=talk.haacksnetworking.org Environment=TALK_PORT=3478 Environment=TZ=America/Denver Environment=TURN_SECRET=replace-with-your-turn-secret Environment=SIGNALING_SECRET=replace-with-your-signaling-secret Environment=INTERNAL_SECRET=replace-with-your-internal-secret Environment=SKIP_CERT_VERIFY=false PodmanArgs=--init --cpus=2 --memory=4g [Service] Restart=always TimeoutStopSec=120 [Install] WantedBy=default.target EOF systemctl --user daemon-reload systemctl --user reset-failed container-talk-hpb.service systemctl --user start container-talk-hpb.service sleep 25 ==== 3. Extra Nextcloud backends (after every start) ==== The HPB container can only be built with one endpoint when it is updated, so the following is needed to add xx amount of endpoints to use the HPB with: podman exec talk-hpb sh -c ' printf "\n[backend-2]\nurls = https://cloud.gnulinux.vip\nsecret = replace-with-your-signaling-secret\nmaxstreambitrate = 1048576\nmaxscreenbitrate = 2097152\n" >> /conf/signaling.conf printf "\n[backend-3]\nurls = https://inside.outsidebox.club\nsecret = replace-with-your-signaling-secret\nmaxstreambitrate = 1048576\nmaxscreenbitrate = 2097152\n" >> /conf/signaling.conf printf "\n[backend-4]\nurls = https://cloud.friend.info\nsecret = replace-with-your-signaling-secret\nmaxstreambitrate = 1048576\nmaxscreenbitrate = 2097152\n" >> /conf/signaling.conf sed -i "s/backends = backend-1/backends = backend-1, backend-2, backend-3, backend-4/" /conf/signaling.conf ' podman exec talk-hpb sh -c 'kill $(ps | awk "/nextcloud-spreed-signaling|[s]ignaling/{print \$1; exit}")' podman exec talk-hpb grep -A5 '^\[backend' /conf/signaling.conf When you run this, you get something like: [backend] backends = backend-1, backend-2, backend-3, backend-4 ... [backend-1] urls = https://cloud.haacksnetworking.org ... [backend-2] urls = https://cloud.gnulinux.vip ... [backend-3] urls = https://inside.outsidebox.club ... [backend-4] urls = https://cloud.friend.info ==== 4. Verify ==== Once your back-ends are all specified, let's verify the service is healthy and the api endpoint is reachable: systemctl --user is-active container-talk-hpb.service podman inspect talk-hpb --format '{{.Name}} cpus={{.HostConfig.NanoCpus}} memory={{.HostConfig.Memory}}' curl -sI http://127.0.0.1:8088/standalone-signaling/api/v1/welcome We should see something like ''active'', ''cpus=2000000000'', ''memory=4294967296'', and an HTTP response from the welcome endpoint. ==== 5. Upgrade script ==== Let's create an upgrade script at ''nano /usr/local/bin/upgrade-high-performance.sh''. Inside it, let's put something like this: #!/bin/bash set -euo pipefail export XDG_RUNTIME_DIR=/run/user/$(id -u) export DBUS_SESSION_BUS_ADDRESS=unix:path=${XDG_RUNTIME_DIR}/bus podman pull ghcr.io/nextcloud-releases/aio-talk:latest systemctl --user stop container-talk-hpb.service systemctl --user daemon-reload systemctl --user reset-failed container-talk-hpb.service systemctl --user start container-talk-hpb.service sleep 25 podman exec talk-hpb sh -c ' printf "\n[backend-2]\nurls = https://cloud.gnulinux.vip\nsecret = replace-with-your-signaling-secret\nmaxstreambitrate = 1048576\nmaxscreenbitrate = 2097152\n" >> /conf/signaling.conf printf "\n[backend-3]\nurls = https://inside.outsidebox.club\nsecret = replace-with-your-signaling-secret\nmaxstreambitrate = 1048576\nmaxscreenbitrate = 2097152\n" >> /conf/signaling.conf printf "\n[backend-4]\nurls = https://cloud.friend.info\nsecret = replace-with-your-signaling-secret\nmaxstreambitrate = 1048576\nmaxscreenbitrate = 2097152\n" >> /conf/signaling.conf sed -i "s/backends = backend-1/backends = backend-1, backend-2, backend-3, backend-4/" /conf/signaling.conf ' podman exec talk-hpb sh -c 'kill $(ps | awk "/nextcloud-spreed-signaling|[s]ignaling/{print \$1; exit}")' curl -sI http://127.0.0.1:8088/standalone-signaling/api/v1/welcome If your curl output is unhealthy, stop and debug before proceeding. ==== 6. Apache reverse proxy (root) ==== We can now setup our reverse proxy and associated virtual hosts and Let's Encrypt cert: sudo a2enmod proxy proxy_http proxy_wstunnel headers rewrite ssl authz_host sudo certbot certonly --apache -d talk.haacksnetworking.org Inside ''nano /etc/apache2/sites-available/talk.haacksnetworking.org.conf'' let's put something like: ServerName talk.haacksnetworking.org RewriteEngine On RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] And, inside the TLS virtual host, ''nano /etc/apache2/sites-available/talk.haacksnetworking.org-ssl.conf'' let's drop something like: ServerName talk.haacksnetworking.org ServerAdmin support@haacksnetworking.org SSLEngine on SSLCertificateFile /etc/letsencrypt/live/talk.haacksnetworking.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/talk.haacksnetworking.org/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf ProxyPreserveHost On RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443" RewriteEngine On RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/?(.*) ws://127.0.0.1:8088/$1 [P,L] ProxyPass / http://127.0.0.1:8088/ ProxyPassReverse / http://127.0.0.1:8088/ ErrorLog ${APACHE_LOG_DIR}/talk.haacksnetworking.org-error.log CustomLog ${APACHE_LOG_DIR}/talk.haacksnetworking.org-access.log combined Once the virtual hosts are built, let's enable it, check the config, and then check the endpoint. a2ensite talk.haacksnetworking.org.conf apache2ctl configtest && systemctl reload apache2 curl -sI http://talk.haacksnetworking.org/ curl -sI https://talk.haacksnetworking.org/ Check your output and make sure everything is accessible and running. If not, debug until it works. FYI, the endpoint for clients is ''wss://talk.haacksnetworking.org/spreed''. More updates if/when rebuilds are done will be posted. Reach out on Matrix if you have questions. --- //[[alerts@haacksnetworking.org|oemb1905]] 2026/10/10 05:16//