different nextcloud aio solution

This commit is contained in:
Ebbe Baß
2026-07-30 09:05:37 +02:00
parent da5ee4a161
commit 6795e1979d
3 changed files with 42 additions and 180 deletions
@@ -8,7 +8,7 @@ The optimal setup uses one server per role:
- Nextcloud (Apache + PHP + MariaDB) - Nextcloud (Apache + PHP + MariaDB)
- Collabora CODE (document editing backend) - Collabora CODE (document editing backend)
- Nextcloud Talk HPB (NATS + Janus Gateway + signaling server, via Docker) - Nextcloud Talk HPB (Nextcloud AIO Talk: bundled TURN/STUN + signaling server, via Docker)
The current playbook stack is made for a theoretical infinite amount of Nextcloud instance setups The current playbook stack is made for a theoretical infinite amount of Nextcloud instance setups
(not load balanced or anything in that direction) and a single server each for Collabora CODE and (not load balanced or anything in that direction) and a single server each for Collabora CODE and
@@ -58,7 +58,7 @@ co-locate roles on one server.
After that is done, copy vars/shared_vars.yml.example to vars/shared_vars.yml and go change all After that is done, copy vars/shared_vars.yml.example to vars/shared_vars.yml and go change all
the variables in it according to your needs. Every secret in that file (database password, admin the variables in it according to your needs. Every secret in that file (database password, admin
password, Collabora admin password, Talk HPB signaling/TURN/hash/block secrets) ships with a password, Collabora admin password, Talk HPB TURN/signaling/internal secrets) ships with a
"ChangeMe..." placeholder - replace all of them before deploying. "ChangeMe..." placeholder - replace all of them before deploying.
/nextcloud_full_deployment /nextcloud_full_deployment
@@ -78,13 +78,13 @@ this order, since each one depends on the previous:
3. Connect Collabora CODE to your Nextcloud instance(s): 3. Connect Collabora CODE to your Nextcloud instance(s):
ansible-playbook connect_nextcloud_collabora.yml -i inventory/hosts.ini --ask-become-pass ansible-playbook connect_nextcloud_collabora.yml -i inventory/hosts.ini --ask-become-pass
4. Nextcloud Talk High-Performance Backend (NATS + Janus + signaling server, via Docker): 4. Nextcloud Talk High-Performance Backend (Nextcloud AIO Talk, via Docker):
ansible-playbook deploy_nc_talk_hpb.yml -i inventory/hosts.ini --ask-become-pass ansible-playbook deploy_nc_talk_hpb.yml -i inventory/hosts.ini --ask-become-pass
This playbook only sets up the backend itself. Nextcloud does not pick it up automatically - This playbook only sets up the backend itself. Nextcloud does not pick it up automatically -
finish the connection by hand on each Nextcloud instance under finish the connection by hand on each Nextcloud instance under
Administration -> Talk -> High-performance backend: Administration -> Talk -> High-performance backend:
Signaling server URL: https://<nc_talk_hpb_domain>/standalone-signaling Signaling server URL: https://<nc_talk_hpb_domain>
Shared secret: nc_talk_hpb_signaling_secret (from shared_vars.yml) Shared secret: nc_talk_hpb_signaling_secret (from shared_vars.yml)
TURN server: <nc_talk_hpb_domain>:3478, protocols UDP and TCP TURN server: <nc_talk_hpb_domain>:3478, protocols UDP and TCP
TURN secret: nc_talk_hpb_turn_secret (from shared_vars.yml) TURN secret: nc_talk_hpb_turn_secret (from shared_vars.yml)
@@ -80,7 +80,7 @@
state: started state: started
# ================================================================ # ================================================================
# PLAY 2 — Deploy the HPB stack: NATS, Janus Gateway, Signaling # PLAY 2 — Deploy the HPB stack: Nextcloud AIO Talk (all-in-one)
# ================================================================ # ================================================================
- name: Deploy Nextcloud Talk High-Performance Backend stack - name: Deploy Nextcloud Talk High-Performance Backend stack
hosts: nextcloud_talk_hpb hosts: nextcloud_talk_hpb
@@ -91,167 +91,40 @@
- vars/shared_vars.yml - vars/shared_vars.yml
tasks: tasks:
- name: Create HPB config directory structure - name: Create HPB install directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ item }}" path: "{{ nc_talk_hpb_install_dir }}"
state: directory state: directory
mode: "0750" mode: "0750"
loop:
- "{{ nc_talk_hpb_install_dir }}/config/janus"
- name: Deploy NATS configuration # NOTE: only nextcloud_domain is wired up via NC_DOMAIN here, matching
ansible.builtin.copy:
dest: "{{ nc_talk_hpb_install_dir }}/config/nats.conf"
mode: "0640"
content: |
listen: 127.0.0.1:4222
notify: Restart HPB stack
- name: Deploy Janus main configuration
ansible.builtin.copy:
dest: "{{ nc_talk_hpb_install_dir }}/config/janus/janus.jcfg"
mode: "0640"
content: |
general: {
configs_folder = "/usr/local/etc/janus"
plugins_folder = "/usr/local/lib/janus/plugins"
transports_folder = "/usr/local/lib/janus/transports"
events_folder = "/usr/local/lib/janus/events"
loggers_folder = "/usr/local/lib/janus/loggers"
debug_level = 4
log_to_stdout = true
}
nat: {
ice_lite = false
ice_tcp = false
full_trickle = true
rtp_port_range = "{{ nc_talk_hpb_rtp_port_range }}"
}
media: {
ipv6 = false
}
plugins: {
}
transports: {
}
notify: Restart HPB stack
- name: Deploy Janus WebSocket transport configuration
ansible.builtin.copy:
dest: "{{ nc_talk_hpb_install_dir }}/config/janus/janus.transport.websockets.jcfg"
mode: "0644"
content: |
general: {
ws = true
ws_port = 8188
}
admin: {
admin_ws = true
admin_ws_port = 7188
}
notify: Restart HPB stack
- name: Deploy Janus VideoRoom plugin configuration
ansible.builtin.copy:
dest: "{{ nc_talk_hpb_install_dir }}/config/janus/janus.plugin.videoroom.jcfg"
mode: "0640"
content: |
general: {
admin_key = "{{ nc_talk_hpb_janus_admin_key }}"
}
notify: Restart HPB stack
# NOTE: only nextcloud_domain is wired up as a backend here, matching
# the single-Nextcloud-instance scope of the rest of this playbook # the single-Nextcloud-instance scope of the rest of this playbook
# stack. To serve more Nextcloud instances from this HPB, add further # stack. For multi-domain/multi-tenant setups, see the Nextcloud Talk
# backendN blocks below by hand and list them in [backend] backends - # HPB multi-domain documentation and adjust NC_DOMAIN by hand.
# they must all share the same signaling secret.
- name: Deploy signaling server configuration
ansible.builtin.copy:
dest: "{{ nc_talk_hpb_install_dir }}/config/server.conf"
mode: "0644"
content: |
[http]
listen = 0.0.0.0:8081
[app]
secret = {{ nc_talk_hpb_signaling_secret }}
[sessions]
hashkey = {{ nc_talk_hpb_hash_key }}
blockkey = {{ nc_talk_hpb_block_key }}
[nats]
url = nats://127.0.0.1:4222
[mcu]
type = janus
url = ws://127.0.0.1:8188
[backend]
backends = backend1
[backend1]
url = https://{{ nextcloud_domain }}
secret = {{ nc_talk_hpb_signaling_secret }}
[turn]
api = static
apikey = {{ nc_talk_hpb_turn_secret }}
secret = {{ nc_talk_hpb_turn_secret }}
servers = turn:{{ nc_talk_hpb_domain }}:3478?transport=udp,turn:{{ nc_talk_hpb_domain }}:3478?transport=tcp
notify: Restart HPB stack
- name: Deploy HPB Docker Compose stack definition - name: Deploy HPB Docker Compose stack definition
ansible.builtin.copy: ansible.builtin.copy:
dest: "{{ nc_talk_hpb_install_dir }}/docker-compose.yml" dest: "{{ nc_talk_hpb_install_dir }}/docker-compose.yml"
mode: "0640" mode: "0640"
content: | content: |
name: 'hpb' name: 'hpb'
services: services:
nats: nc-talk:
container_name: nats_server container_name: talk_hpb
image: nats:latest image: ghcr.io/nextcloud-releases/aio-talk:latest
command: ["-c", "/config/nats.conf"] init: true
volumes: ports:
- {{ nc_talk_hpb_install_dir }}/config/nats.conf:/config/nats.conf:ro - 3478:3478/tcp
network_mode: host - 3478:3478/udp
restart: unless-stopped - 8181:8081/tcp
janus:
container_name: janus_gateway
image: canyan/janus-gateway:latest
command: ["/usr/local/bin/janus", "--configs-folder=/usr/local/etc/janus"]
network_mode: host
ulimits:
nofile:
soft: 65536
hard: 65536
environment: environment:
- JANUS_API_HTTP=yes - NC_DOMAIN={{ nextcloud_domain }}
- JANUS_API_HTTPS=no - TALK_HOST={{ nc_talk_hpb_domain }}
- JANUS_API_WS=yes - TURN_SECRET={{ nc_talk_hpb_turn_secret }}
- JANUS_API_ADMIN_WS=yes - SIGNALING_SECRET={{ nc_talk_hpb_signaling_secret }}
- JANUS_RTP_PORT_RANGE={{ nc_talk_hpb_rtp_port_range }} - TZ={{ nc_talk_hpb_timezone }}
volumes: - TALK_PORT=3478
- {{ nc_talk_hpb_install_dir }}/config/janus:/usr/local/etc/janus:ro - INTERNAL_SECRET={{ nc_talk_hpb_internal_secret }}
restart: unless-stopped
signaling:
container_name: spreed_signaling
image: strukturag/nextcloud-spreed-signaling:latest
depends_on:
- nats
- janus
network_mode: host
volumes:
- {{ nc_talk_hpb_install_dir }}/config/server.conf:/config/server.conf:ro
restart: unless-stopped restart: unless-stopped
notify: Restart HPB stack notify: Restart HPB stack
@@ -311,7 +184,6 @@
loop: loop:
- proxy - proxy
- proxy_http - proxy_http
- proxy_wstunnel
- rewrite - rewrite
- headers - headers
- ssl - ssl
@@ -323,10 +195,11 @@
enabled: true enabled: true
state: started state: started
# NOTE: coolwsd-style TLS termination happens here in Apache; the # NOTE: the AIO Talk container serves its own HTTP/WSS API on
# signaling container listens on plain HTTP/WS on 127.0.0.1:8081 # 127.0.0.1:8181 (mapped from its internal 8081); TLS for the signal
# (see server.conf's [http] listen), so the proxy targets ws/http, # domain is terminated here in Apache, proxying the whole domain (no
# not wss/https. # subpath) via mod_proxy_http's native WebSocket upgrade support
# (upgrade=websocket, Apache 2.4.47+) instead of mod_proxy_wstunnel.
- name: Deploy Talk HPB Apache virtual host (HTTP redirect + HTTPS proxy) - name: Deploy Talk HPB Apache virtual host (HTTP redirect + HTTPS proxy)
ansible.builtin.copy: ansible.builtin.copy:
dest: /etc/apache2/sites-available/nc-talk-hpb.conf dest: /etc/apache2/sites-available/nc-talk-hpb.conf
@@ -347,12 +220,11 @@
ProxyPreserveHost On ProxyPreserveHost On
RewriteEngine On RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
RewriteCond %{HTTP:Upgrade} =websocket [NC] RequestHeader set X-Real-IP expr=%{REMOTE_ADDR}
RewriteRule /standalone-signaling/(.*) ws://127.0.0.1:8081/$1 [P,L]
ProxyPass /standalone-signaling/ http://127.0.0.1:8081/ ProxyPass / http://127.0.0.1:8181/ upgrade=websocket
ProxyPassReverse /standalone-signaling/ http://127.0.0.1:8081/ ProxyPassReverse / http://127.0.0.1:8181/
ErrorLog ${APACHE_LOG_DIR}/nc_talk_hpb_error.log ErrorLog ${APACHE_LOG_DIR}/nc_talk_hpb_error.log
CustomLog ${APACHE_LOG_DIR}/nc_talk_hpb_access.log combined CustomLog ${APACHE_LOG_DIR}/nc_talk_hpb_access.log combined
@@ -385,12 +257,6 @@
- tcp - tcp
- udp - udp
- name: Allow RTP port range through the firewall
community.general.ufw:
rule: allow
port: "{{ nc_talk_hpb_rtp_port_range | replace('-', ':') }}"
proto: udp
# --------------------------------------------------------------- # ---------------------------------------------------------------
# Handlers # Handlers
# --------------------------------------------------------------- # ---------------------------------------------------------------
@@ -42,26 +42,22 @@ fail2ban_dir: "/etc/fail2ban"
nc_talk_hpb_domain: "talk-hpb.cloud.example.com" nc_talk_hpb_domain: "talk-hpb.cloud.example.com"
# Where the NATS/Janus/Signaling Docker Compose stack and its config live on the HPB host. # Where the Nextcloud AIO Talk Docker Compose stack and its config live on the HPB host.
nc_talk_hpb_install_dir: "/opt/hpb" nc_talk_hpb_install_dir: "/opt/hpb"
# Talk HPB TLS certificate paths (used by the Apache reverse proxy). # Talk HPB TLS certificate paths (used by the Apache reverse proxy).
nc_talk_hpb_ssl_cert: "/etc/ssl/certs/nc-talk-hpb-selfsigned.crt" nc_talk_hpb_ssl_cert: "/etc/ssl/certs/nc-talk-hpb-selfsigned.crt"
nc_talk_hpb_ssl_key: "/etc/ssl/private/nc-talk-hpb-selfsigned.key" nc_talk_hpb_ssl_key: "/etc/ssl/private/nc-talk-hpb-selfsigned.key"
# UDP port range Janus uses for WebRTC media (RTP). Must also be reachable through the firewall. # Timezone used inside the Talk HPB container.
nc_talk_hpb_rtp_port_range: "20000-40000" nc_talk_hpb_timezone: "Europe/Berlin"
# Admin key for the Janus VideoRoom plugin (lets the signaling server manage rooms via the admin API). # Shared secrets for the Nextcloud AIO Talk container. Generate each with the given
nc_talk_hpb_janus_admin_key: "ChangeMe1234_" # command and paste the result here (min. 24 chars, better 32).
# turn/signaling/internal: openssl rand -hex 32
# Shared secrets for the signaling server. Generate each with the given command and paste the result here.
# turn/signaling/hash: openssl rand -hex 32 (64 hex chars)
# block: openssl rand -hex 16 (32 hex chars — MUST be exactly 32, 48 or 64 hex chars or the signaling server refuses to start)
nc_talk_hpb_turn_secret: "ChangeMe_RunOpensslRandHex32" nc_talk_hpb_turn_secret: "ChangeMe_RunOpensslRandHex32"
nc_talk_hpb_signaling_secret: "ChangeMe_RunOpensslRandHex32" nc_talk_hpb_signaling_secret: "ChangeMe_RunOpensslRandHex32"
nc_talk_hpb_hash_key: "ChangeMe_RunOpensslRandHex32" nc_talk_hpb_internal_secret: "ChangeMe_RunOpensslRandHex32"
nc_talk_hpb_block_key: "ChangeMe_RunOpensslRandHex16"
######################################## ########################################
# Collabora CODE # Collabora CODE