Since Nextcloud has released the High Performance Backend as OpenSource under AGPL License, i tried my luck to install it on Ubuntu without docker, but many people had problems or run other OS as Ubuntu/Debian and asked „what about docker?“. Ok, without is a little bit tricky, so let us go with docker:
Requirements:
– a VPS with docker and docker-compose (Tested on Ubuntu 18.04 and 20.04 LTS) (you can get one here @netcup with 5€ Discount or start at Hetzner Cloud with 20€ start credits)
– shell access and appropriate rights
– One DNS A and possibly AAAA record for our nginx vhost and stun/turn-server (I use signaling.example.com for all three services in this guide)
– Optional – a second DNS A and possibly AAAA record for stun/turnserver
Hardware Requirements:
4 CPU
8 GB RAM
32 GB Disk-Space
See also: Nextcloud Portal
You can also test a smaller server if you don’t have that many users
Step 1: Install Firewall and other packages
First of all, you should install a firewall to secure your VPS (if not installed) and allow incoming traffic to port 80/443, 22 (ssh) and for coturn on port 3478tcp/udp only. For Securing ssh-access you can use fail2ban and passwordless authentication. Many guides for this are out there.
apt install ufw -y ufw allow http ufw allow https ufw allow ssh ufw allow 3478/tcp ufw allow 3478/udp ufw enable
Accept with „y“
Step 2: Install git, docker and docker-compose
Install docker:
curl -sSL https://get.docker.com/ | CHANNEL=stable sh systemctl enable docker.service systemctl start docker.service
and now docker-compose and git with:
sudo apt install -y docker-compose git
Step 3: Clone git-Repository and build Images
we clone the git-Repository to /opt
cd /opt/ git clone https://github.com/strukturag/nextcloud-spreed-signaling.git && cd nextcloud-spreed-signaling
create a random hex key (STATIC_SECRET) for your nextcloud talk app and signaling server with:
openssl rand -hex 32
and a hashkey:
openssl rand -base64 16
a blockkey:
openssl rand -base64 16
a Nextcloud SHARED_SECRET for Signaling:
openssl rand -hex 16
an API-KEY:
openssl rand -base64 16
and copy all for later use, then edit docker-compose.yml
nano docker-compose.yml
adjust the following entries REALM and STATIC_SECRET:
version: '3' services: spreedbackend: build: . volumes: - ./server.conf:/config/server.conf network_mode: host restart: unless-stopped depends_on: - nats - janus - coturn nats: image: nats:2.1 volumes: - ./gnatsd.conf:/config/gnatsd.conf command: ["-c", "/config/gnatsd.conf"] network_mode: host restart: unless-stopped janus: build: docker/janus command: ["janus", "--full-trickle"] network_mode: host restart: unless-stopped coturn: build: docker/coturn network_mode: host environment: REALM: signaling.example.com STATIC_SECRET: openssl rand -hex 32 restart: unless-stopped
then generate server.conf:
nano server.conf
and copy and paste the following (please adjust your backends and secrets):
[http] listen = 127.0.0.1:8080 [app] debug = false [sessions] hashkey = openssl rand -base64 16 blockkey = openssl rand -base64 16 [backend] backends = backend-1 #here you can add more backends commaseparated backend-1, backend-2, backend-3 allowall = false timeout = 10 connectionsperhost = 8 [backend-1] url = https://nextcloud.example.com secret = openssl rand -hex 16 #[backend-2] #url = https://nextcloud2.example.com #secret = openssl rand -hex 16 #[backend-3] #url = https://nextcloud3.example.com #secret = openssl rand -hex 16 [nats] url = nats://localhost:4222 [mcu] type = janus url = ws://localhost:8188 [turn] apikey = openssl rand -base64 16 secret = openssl rand -hex 32 servers = turn:localhost:3478?transport=udp,turn:localhost:3478?transport=tcp
save file and change rights to 644:
chmod 644 server.conf
and then build the images:
docker-compose build
you have to wait a little bit before you can continue.
then bring the complete stack up with:
docker-compose up -d
now you should have at least 4 containers running:
docker ps
then go to next step.
Step 4: Install nginx and create vHost for signaling server
Now we will install nginx as reverse proxy for our high performance backend:
apt install nginx python3-certbot-nginx -y
and create the vHost:
nano /etc/nginx/sites-available/signaling
copy, paste and adjust:
server { listen 80; server_name signaling.example.com; }
and activate vhost:
ln -s /etc/nginx/sites-available/signaling /etc/nginx/sites-enabled/signaling
then check with:
nginx -t
and reload
systemctl reload nginx
now use certbot to obtain a certificate:
certbot --authenticator standalone --installer nginx -d signaling.example.com --pre-hook "service nginx stop" --post-hook "service nginx start"
then paste the following config in the vHost-conf:
mv /etc/nginx/sites-available/signaling /tmp/signaling.bak && nano /etc/nginx/sites-available/signaling
upstream signaling { server 127.0.0.1:8080; } server { server_name signaling.example.com; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/signaling.example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/signaling.example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; location /standalone-signaling/ { proxy_pass http://signaling/; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /standalone-signaling/spreed { proxy_pass http://signaling/spreed; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } server { if ($host = signaling.example.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name signaling.example.com; return 404; # managed by Certbot }
and check an reload nginx:
nginx -t
if ok
systemctl reload nginx
Step 5: Configure nextcloud to use stun/turn and signaling server
Now we are ready to add turn/stun- and signaling-server to our Nextcloud
Go to Settings, Talk and enter the following:
And then enjoy your High Performance Backend.
Problems with the tutorial? Then comment below or contact me per Mail or Mastodon.
I will be happy if you would support my work here.
Happy nextclouding and do not forget to share ?
If you want to try an easier solution look at this deeztek @ github
Sources:
Picture from Alexandra_Koch on Pixabay
Struktur AG
Tested on netcup
Tested on Hetzner Cloud
21 Gedanken zu „How to run Nextcloud Talk High Performance Backend with Stun/Turnserver on Ubuntu with docker-compose“
Danke Markus! Das Hilft 🙂 Ich habe es mit einem kleinen Dev VM bei Scaleway getestet (2GB RAM, 20GB SSD (DEV1-S) mit 300Mbps Anbindung.
Thank you, Markus. That’s helpful. I successfully tested this on a DEV1-S instance at Scaleway (2GB RAM, 20GB SSD, 300Mbps connection).
Hi Markus,
Great tutorial. Very helpful. In case anyone is interested, I took your tutorial as inspiration and created a derivative going with a complete Docker solution. Code and instructions are here:
https://github.com/deeztek/deeztek-docker/tree/master/Linux/nextcloud-spreed-signaling
Thanks
Hi,
very nice work! Thank you for sharing 🙂
Markus
Hallo,
ich bekomme in meiner Nextcloud angezeigt, dass der Turn Server keine funktionierenden ICE-Kandidaten zurücksendet.
Wo hab ich da eventuell einen Fehler gemacht?
Beste Grüße,
Robert
Hi, befindet sich Dein Client hinter einer Firewall, die die Turnserver-Ports nicht zulässt? Falls nicht, hilft manchmal auch ein anderer Browser.
Danke für dieses Kochrezept. Ich hab’s nun nach wochenlangem tüfteln endlich geschafft. Super Job, Danke
Hallo Markus,
nach mehreren erfolglosen Versuchen einen Signalingserver einzurichten stehe ich nun mit einem großen ? über dem Kopf da.
Ausgangslage: Eine „nackte“ VPS mit ubuntu 20.04 LTS.
Ich bin Schritt für Schritt nach deine Anleitung vorgegangen., bekomme aber auf der Nextcloud-Seite beim „Hochleistungs-Backend“ die Meldung „Fehler: Der Server antwortet mit: 404“. Hast du eine Idee wo ich anfangen kann zu suchen?
Hallo Bernd,
Bei Error 404 zuerst in den nginx-error.log schauen.
Gruß Markus
Hi Markus,
Danke für deine Anleitung!
Ich komme leider bei Schritt 4 nicht weiter, da ich noch nie mit nginx gearbeitet habe und gerne weiterhin apache2 verwenden würde.
Weißt du wie ich das als apache config dateien umsetzen kann?
Würdest mir sehr weiterhelfen!
Hi Dominik,
Apache2 sieht so aus:
ServerName signaling.example.com
ServerAdmin webmaster@example.com
DocumentRoot /var/www/html
# Enable proxying Websocket requests to the standalone signaling server.
ProxyPass „/standalone-signaling/“ „ws://127.0.0.1:8080/“
RewriteEngine On
# Websocket connections from the clients.
RewriteRule ^/standalone-signaling/spreed$ – [L]
# Backend connections from Nextcloud.
RewriteRule ^/standalone-signaling/api/(.*) http://127.0.0.1:8080/api/$1 [L,P]
SSLCertificateFile /etc/letsencrypt/live/signaling.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/signaling.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
Gruß
Markus
Hi Markus,
Danke dir für die schnelle Antwort! Leider klappt es immer noch nicht ganz.
Port 8080 ist belegt, also habe ich in der server.conf und der apache signaling conf den Port auf 8086 gelegt. Das sollte ja keine Problem sein, oder?
Wenn ich in den nextcloud Einstellungen nun den signaling-server hinzufüge kommt lediglich
„Fehler: Der Server antwortete mit: 503“.
Im apache error file heißt es:
(111)Connection refused: AH00957: HTTP: attempt to connect to 127.0.0.1:8086 (*) failed
AH01114: HTTP: failed to make connection to backend: 127.0.0.1
lsof -i:8086 liefert kein Ergebnis.
Hast du eine Idee, woran das liegen kann?
Hi Dominik,
Ist das proxy_wstunnel Modul geladen?
sudo a2enmod proxy_wstunnel
Hi Markus,
Scheint so:
Module proxy already enabled
Module proxy_wstunnel already enabled
netstat -tulpen | grep 8086 ?
Ach, sorry, im ersten Kommentar hatte ich überlesen, dass Du den Port schon geprüft hattest.
Da scheint der Container nicht richtig zu laufen.
docker logs nextcloud-spreed-signaling_spreedbackend_1
Hi Markus,
docker logs liefert:
2021-01-23 11:00:04.346995 I | natsclient.go:101: Could not create connection (nats: no servers available for connection), will retry in 8s
nats läuft jedoch und sudo netstat -tulpen | grep 4222 liefert:
tcp6 0 0 :::4222 :::* LISTEN 0 2325896 20969/nats-server
Schau mal ob der Nats-Container stabil läuft oder ständig restartet.
Hallo Markus, vielen Dank für die tolle Anleitung.
Ich würde gern verstehen, warum die Docker Container das Host Netzwerk verwenden. Können diese nicht in einem eigenen Docker Netzwerk kommunizieren und nur Port 80 und 3478 exposen?
Den nginx würde ich gerne über den jwilder/nginx-proxy laufen lassen, da auch noch andere Services auf dem Server darüber laufen und auch https mit letsencrypt darüber laufen.
Wäre super, wenn du dazu deine Einschätzung geben könntest, ob das funktionieren müßte.
Hallo Mario, sollte eigentlich funktionieren. Dies hier ist nur die straightforward Anleitung für einen dedizierten Server/ VM für signaling.
Gruß Markus
Danke für die gute und übersichtliche Anleitung! Das hat bei meiner Cloud gut funktioniert und Talk endlich sinnvoll nutzbar gemacht.
Danke für das Feedback. Freut mich zu hören.