前回は Nextcloud を AlmaLinux 9 + OpenLiteSpeed の環境にセットアップしました。
この Nextcloud に Talk アプリ(https://apps.nextcloud.com/apps/spreed)をインストールしたところ、高性能バックエンド(HPB: High-performance backend)を設定するように促されました。

Nextcloud Talk は自前でチャットやビデオ通話の環境を持つことができるためとても重宝していますが、HPB を設定しないと 3 人以上のビデオ通話が不安定になってしまいます。
そこで今回は HPB を構築していきます。
環境
- OS: AlmaLinux release 9.5 (Teal Serval)
- Web サーバー: OpenLiteSpeed 1.8.3
- Nextcloud:
- Nextcloud Hub 10(31.0.5)
- Talk 21.0.4
- ホスティング: ConoHa VPS(メモリ 2GB)
高性能バックエンドの構築
前回に引き続き Docker イメージの All-in-One は使わず個別に設定をしていきます。
幸いにも Nextcloud 社公式パートナーの株式会社スタイルズから導入手順の例が公開されていますので、それに沿ってやっていく事にします。

coTURN
coTURN は、NAT やファイヤーウォールの背後に位置する端末間の IP 接続を確立するために必要な中継サーバである STUN(Session Traversal Utilities for NAT)/ TURN(Traversal Using Relays around NAT)サーバです。
coTURN のインストール
Enterprise Linux 9 では EPEL リポジトリに登録されていましたので、そこからインストールします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # dnf install coturn Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: coturn x86_64 4.6.3-1.el9 epel 275 k Installing dependencies: hiredis x86_64 1.0.2-2.el9 epel 47 k libpq x86_64 13.20-1.el9_5 appstream 207 k Installing weak dependencies: telnet x86_64 1:0.17-85.el9 appstream 63 k Transaction Summary ================================================================================ Install 4 Packages Total download size: 593 k Installed size: 2.2 M Is this ok [y/N]: y |
coTURN の設定
Nextcloud の公式ドキュメントに coTURN の詳細な設定方法がありますので、こちらを参考に設定します。
SSL 証明書を読み込むために、root が coTURN サービスを実行するように設定します。
1 | # systemctl edit coturn |
1 2 3 | [Service] User=root Group=root |
次に、TURN サーバーシークレットを生成しておきます。
1 2 | # openssl rand -hex 32 (TURN サーバーシークレット) |
coTURN の設定ファイル(/etc/coturn/turnserver.conf)を編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #external-ip=60.70.80.91 ↓ サーバーのグローバル IP を指定 external-ip=xxx.xxx.xxx.xxx #fingerprint ↓ コメント解除 fingerprint #use-auth-secret ↓ コメント解除 use-auth-secret #static-auth-secret=north ↓ TURN サーバーシークレットを指定 static-auth-secret=(TURN サーバーシークレット) #realm=mycompany.org ↓ Nextcloud(Talk)のドメインを指定 realm=example.com #total-quota=0 ↓ コメント解除 total-quota=0 #bps-capacity=0 ↓ コメント解除 bps-capacity=0 #cert=/etc/pki/coturn/public/turn_server_cert.pem ↓ cert.pem を指定(TURNS を使用する場合) cert=/etc/letsencrypt/live/example.com/cert.pem #pkey=/etc/pki/coturn/private/turn_server_pkey.pem ↓ privkey.pem を指定(TURNS を使用する場合) pkey=/etc/letsencrypt/live/example.com/privkey.pem #no-cli ↓ コメント解除 no-cli |
coTURN サービスのスタートと自動起動を設定します。
1 2 | # systemctl start coturn # systemctl enable coturn |
Janus
WebRTC(Web Real-Time Communication)サーバーの Janus をインストールしていきます。
Ubuntu 24.04 では apt でインストールできるようですが、Enterprise Linux 9 用のパッケージは見つけることができませんでした。
Snap のインストール
Snap Store で janus-gateway を見つけることができましたので、まずは Snap のインストールを行っていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # dnf install snapd Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: snapd x86_64 2.68.3-0.el9 epel 18 M Installing dependencies: snap-confine x86_64 2.68.3-0.el9 epel 2.9 M snapd-selinux noarch 2.68.3-0.el9 epel 86 k xdelta x86_64 3.1.0-17.el9 epel 87 k Transaction Summary ================================================================================ Install 4 Packages Total download size: 21 M Installed size: 69 M Is this ok [y/N]: y |
Snap がソケットを使って通信するための、systemd ユニットを有効化します。
1 2 | # systemctl enable --now snapd.socket Created symlink /etc/systemd/system/sockets.target.wants/snapd.socket → /usr/lib/systemd/system/snapd.socket. |
janus-gateway のインストール
Snap で janus-gateway をインストールします。
1 2 3 4 5 6 7 | # snap install janus-gateway INFO Waiting for automatic snapd restart... Warning: /var/lib/snapd/snap/bin was not found in your $PATH. If you've not restarted your session since you installed snapd, try doing that. Please see https://forum.snapcraft.io/t/9469 for more details. janus-gateway v1.3.0 from Sergey Radionov (rsatom) installed |
janus-gateway v1.3.0 がインストールされました。
janus-gateway の設定
TURN REST API キーを生成します。
1 2 | # openssl rand -base64 16 (TURN REST API キー) |
Janus の設定ファイル(/var/snap/janus-gateway/common/etc/janus.jcfg)を編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | general: { #log_to_file = "/path/to/janus.log" ↓ ログのパスを指定 log_to_file = "/var/log/janus/janus.log" #debug_timestamps = true ↓ コメント解除 debug_timestamps = true } nat: { #stun_server = "stun.voip.eutelia.it" #stun_port = 3478 ↓ STUN サーバー、ポート指定 stun_server = "hpb.example.com" stun_port = 3478 #nat_1_1_mapping = "1.2.3.4" ↓ グローバル IP を指定 nat_1_1_mapping = "xxx.xxx.xxx.xxx" #turn_rest_api_key = "anyapikeyyoumayhaveset" ↓ 生成した TURN REST API キーを指定 turn_rest_api_key = "(TURN REST API キー)" } plugins: { #disable = "libjanus_echotest.so,libjanus_recordplay.so" ↓ disable = "libjanus_audiobridge.so, libjanus_duktape.so, libjanus_echotest.so, libjanus_lua.so, libjanus_nosip.so, libjanus_recordplay.so, libjanus_sip.so, libjanus_sipre.so, libjanus_streaming.so, libjanus_textroom.so, libjanus_videocall.so, libjanus_voicemail.so" } transports: { #disable = "libjanus_rabbitmq.so" ↓ disable = "libjanus_http.so, libjanus_mqtt.so, libjanus_nanomsg.so, libjanus_pfunix.so, libjanus_rabbitmq.so" } events: { #disable = "libjanus_sampleevh.so" ↓ disable = "libjanus_gelfevh.so, libjanus_mqttevh.so, libjanus_nanomsgevh.so, libjanus_rabbitmqevh.so, libjanus_sampleevh.so, libjanus_wsevh.so" } |
ルームの設定ファイル(/var/snap/janus-gateway/common/etc/janus.plugin.videoroom.jcfg)を編集して、Demo Room の設定を全てコメントアウトします。
1 2 3 4 5 6 7 8 9 10 11 | #room-1234: { # description = "Demo Room" # secret = "adminpwd" # publishers = 6 # bitrate = 128000 # This is a low cap, increase if you want to use simulcast or SVC # fir_freq = 10 # #audiocodec = "opus" # #videocodec = "vp8" # record = false # #rec_dir = "/path/to/recordings-folder" #} |
WebSocket の設定ファイル(/var/snap/janus-gateway/common/etc/janus.transport.websockets.jcfg)を編集して、アドレスを指定します。
1 2 3 4 5 | general: { #ws_ip = "192.168.0.1" ↓ アドレスを指定 ws_ip = "127.0.0.1" } |
サービスの起動順序を編集します。
1 | # systemctl edit --full snap.janus-gateway.janus-gateway.service |
Unit の After に coturn.service を追加し、coTURN の後に Janus が起動するように指定します。
1 2 3 4 | [Unit] After=var-lib-snapd-snap-janus\x2dgateway-2420.mount network.target snapd.apparmor.service ↓ 最後に coturn.service を追加 After=var-lib-snapd-snap-janus\x2dgateway-2420.mount network.target snapd.apparmor.service coturn.service |
janus-gateway サービスのスタートと自動起動を設定しようとしましたが、サービスが既に開始されていて、自動起動も設定されていました。設定変更を反映するため再起動だけしておきました。
1 2 3 4 5 6 7 8 9 | # systemctl status snap.janus-gateway.janus-gateway.service ● snap.janus-gateway.janus-gateway.service - Service for snap application janus-gateway.janus-gateway Loaded: loaded (/etc/systemd/system/snap.janus-gateway.janus-gateway.service; enabled; preset: disabled) Active: active (running) # systemctl is-enabled snap.janus-gateway.janus-gateway.service enabled # systemctl daemon-reload # systemctl restart snap.janus-gateway.janus-gateway.service |
NATS
NATS(Neural Automatic Transport System)は、軽量でハイパフォーマンスなメッセージングシステムを提供するミドルウェアです。
こちらも Ubuntu 24.04 では apt でインストールできるようですが、Enterprise Linux 9 用のリポジトリでパッケージを見つけることができませんでした。
nats-server のインストール
nats-server の公式サイトでRPM が配布されていたので、そこから最新版をインストールすることにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # dnf install https://github.com/nats-io/nats-server/releases/download/v2.11.4/nats-server-v2.11.4-amd64.rpm nats-server-v2.11.4-amd64.rpm 7.8 MB/s | 6.2 MB 00:00 Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: nats-server x86_64 2.11.4-1 @commandline 6.2 M Transaction Summary ================================================================================ Install 1 Package Total size: 6.2 M Installed size: 16 M Is this ok [y/N]: y |
ユーザーの追加
nats ユーザー/グループを、システムアカウントとして作成しておきます。
1 2 | # groupadd --system nats # useradd --system --gid nats --shell /sbin/nologin --comment "NATS Server" nats |
ユニットファイルを作成
以下を参考に、ユニットファイル(/etc/systemd/system/nats-server.service)を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | [Unit] Description=NATS Server After=network-online.target [Service] PrivateTmp=true Type=simple ExecStart=/usr/bin/nats-server -c /etc/nats-server.conf ExecReload=/bin/kill -s HUP $MAINPID # The nats-server uses SIGUSR2 to trigger Lame Duck Mode (LDM) shutdown # https://docs.nats.io/running-a-nats-service/nats_admin/lame_duck_mode ExecStop=/bin/kill -s SIGUSR2 $MAINPID # This should be `lame_duck_duration` + some buffer to finish the shutdown. # By default, `lame_duck_duration` is 2 mins. TimeoutStopSec=150 Restart=on-failure User=nats Group=nats [Install] WantedBy=multi-user.target |
1 | # systemctl daemon-reload |
設定ファイル(/etc/nats-server.conf)を作成します。
1 | listen: 127.0.0.1:4222 |
nats-server サービスのスタートと自動起動を設定します。
1 2 3 | # systemctl start nats-server # systemctl enable nats-server Created symlink /etc/systemd/system/multi-user.target.wants/nats-server.service → /etc/systemd/system/nats-server.service. |
Signaling
いよいよ Nextcloud Talk 用のシグナリングサーバーをインストールしていきます。
Spreed standalone signaling server はパッケージが用意されていないため、ソースコードからビルドする必要があります。また、ビルドするために Go 言語も必要になります。
前提条件パッケージが入っていない場合は、事前にインストールしておいてください。
1 | # dnf install git make golang |
Signaling のインストール
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | # cd /opt/ # git clone https://github.com/strukturag/nextcloud-spreed-signaling.git # cd nextcloud-spreed-signaling/ # make build /usr/bin/go build -ldflags '-X main.version=b74690defb4836ca21c7b8eb0bc8b361c7a27bdb' -o /opt/nextcloud-spreed-signaling/bin/signaling ./server/... go: downloading github.com/dlintw/goconf v0.0.0-20120228082610-dcc070983490 go: downloading github.com/gorilla/mux v1.8.1 go: downloading github.com/nats-io/nats.go v1.42.0 go: downloading github.com/fsnotify/fsnotify v1.9.0 go: downloading github.com/golang-jwt/jwt/v5 v5.2.2 go: downloading github.com/gorilla/securecookie v1.1.2 go: downloading github.com/gorilla/websocket v1.5.3 go: downloading github.com/mailru/easyjson v0.9.0 go: downloading github.com/notedit/janus-go v0.0.0-20200517101215-10eb8b95d1a0 go: downloading github.com/oschwald/maxminddb-golang v1.13.1 go: downloading github.com/pion/sdp/v3 v3.0.13 go: downloading github.com/pquerna/cachecontrol v0.2.0 go: downloading github.com/prometheus/client_golang v1.22.0 go: downloading go.etcd.io/etcd/client/pkg/v3 v3.6.0 go: downloading go.etcd.io/etcd/client/v3 v3.6.0 go: downloading go.uber.org/zap v1.27.0 go: downloading google.golang.org/grpc v1.72.2 go: downloading google.golang.org/protobuf v1.36.6 go: downloading github.com/klauspost/compress v1.18.0 go: downloading github.com/nats-io/nkeys v0.4.11 go: downloading github.com/nats-io/nuid v1.0.1 go: downloading golang.org/x/sys v0.33.0 go: downloading github.com/josharian/intern v1.0.0 go: downloading github.com/pion/randutil v0.1.0 go: downloading github.com/beorn7/perks v1.0.1 go: downloading github.com/cespare/xxhash/v2 v2.3.0 go: downloading github.com/prometheus/client_model v0.6.1 go: downloading github.com/prometheus/common v0.62.0 go: downloading github.com/prometheus/procfs v0.15.1 go: downloading github.com/coreos/go-semver v0.3.1 go: downloading go.etcd.io/etcd/api/v3 v3.6.0 go: downloading go.uber.org/multierr v1.11.0 go: downloading golang.org/x/net v0.38.0 go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb go: downloading golang.org/x/crypto v0.38.0 go: downloading github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 go: downloading github.com/gogo/protobuf v1.3.2 go: downloading github.com/golang/protobuf v1.5.4 go: downloading github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 go: downloading google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb go: downloading github.com/coreos/go-systemd/v22 v22.5.0 go: downloading golang.org/x/text v0.25.0 /usr/bin/go build -ldflags '-X main.version=b74690defb4836ca21c7b8eb0bc8b361c7a27bdb' -o /opt/nextcloud-spreed-signaling/bin/proxy ./proxy/... go: downloading github.com/google/uuid v1.6.0 |
ビルドしたファイルを、所定のディレクトリに配置します。
1 2 3 4 | # cp /opt/nextcloud-spreed-signaling/bin/signaling /usr/bin/ # mkdir /etc/signaling/ # cp /opt/nextcloud-spreed-signaling/server.conf.in /etc/signaling/server.conf # cp /opt/nextcloud-spreed-signaling/dist/init/systemd/signaling.service /etc/systemd/system/signaling.service |
キーに使用する乱数を 3 種類生成します。
1 2 3 4 5 6 7 8 | # openssl rand -hex 32 (セッションハッシュキー) # openssl rand -hex 16 (セッションブロックキー) # openssl rand -hex 32 (HPB の共有秘密鍵) |
設定ファイル(/etc/signaling/server.conf)を編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | [http] #listen = 127.0.0.1:8080 ↓ コメント解除 listen = 127.0.0.1:8080 [sessions] hashkey = the-secret-for-session-checksums ↓ openssl rand -hex 32 で生成したハッシュキー hashkey = (セッションハッシュキー) blockkey = -encryption-key- ↓ openssl rand -hex 16 で生成したブロックキー blockkey = (セッションブロックキー) [backend] #backends = backend-id, another-backend ↓コメント解除、バックエンドを追加 backends = backend-1 # 追加したバックエンドのブロックを追加 [backend-1] # Nextcloud(Talk)のドメインを指定 url = https://example.com # openssl rand -hex 32 で生成した秘密鍵 secret = (HPB の共有秘密鍵) [nats] #url = nats://localhost:4222 ↓ NATS サーバーを指定 url = nats://127.0.0.1:4222 [mcu] #type = ↓ Multipoint Control Unit に Janus を指定 type = janus #url = ↓ Janus サーバーを指定 url = ws://127.0.0.1:8188 [turn] #apikey = the-api-key-for-the-rest-service ↓ /var/snap/janus-gateway/common/etc/janus.jcfg の TURN REST API キー apikey = (TURN REST API キー) #secret = 6d1c17a7-c736-4e22-b02c-e2955b7ecc64 ↓ /etc/coturn/turnserver.conf の TURN サーバーシークレット secret = (TURN サーバーシークレット) #servers = turn:1.2.3.4:9991?transport=udp,turn:1.2.3.4:9991?transport=tcp ↓ TURN サーバーを指定 servers = turn:hpb.example.com:3478?transport=udp,turn:hpb.example.com:3478?transport=tcp |
ユーザーの追加
signaling ユーザー/グループを、システムアカウントとして作成しておきます。
1 2 | # groupadd --system signaling # useradd --system --gid signaling --shell /sbin/nologin --comment "Nextcloud Talk signaling server" signaling |
設定ファイルのアクセス権を signaling ユーザーに変更しておきます。
1 2 | # chmod 600 /etc/signaling/server.conf # chown signaling: /etc/signaling/server.conf |
ユニットファイルを作成
ユニットファイル(/etc/systemd/system/signaling.service)を編集します。
1 2 3 4 | [Unit] Description=Nextcloud Talk signaling server After=network.target WantedBy=multi-user.target |
1 | # systemctl daemon-reload |
signaling サービスのスタートと自動起動を設定します。
1 2 | # systemctl start signaling # systemctl enable signaling |
ファイアウォール の設定
nftables の設定ファイル(/etc/nftables/filter.nft)を編集して、STUN/TURN(S) のポートを許可します。
- STUN/TURN:3478(TCP、UDP)
- TURNS: 5349(TCP、UDP)
Janus: udp 20000-40000TURN: udp 49152-65535
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | table inet filter { … 省略 … chain TCP { # 管理者にのみ解放 # SSH, OLS 管理画面 tcp dport { 22, 7080 } ip saddr @admin accept # 日本国内にのみ開放 # SUBMISSION, IMAPS, STUN/TURN, TURNS tcp dport { 587, 993, 3478, 5349 } ip saddr @domestic accept # 全開放 # SMTP, HTTP, HTTPS tcp dport { 25, 80, 443 } accept } chain UDP { # 日本国内にのみ開放 # TURN, TURNS udp dport { 3478, 5349 } ip saddr @domestic accept # TURN, TURNS, Janus(こっちは使わなかった) #udp dport { 3478, 5349, 20000-40000, 49152-65535 } ip saddr @domestic accept # 全開放 # http/3 udp dport { 443 } accept } } |
今回は国内向けにポートを開放しましたが、環境に合わせて調整してください。
1 | # systemctl reload nftables |
OpenLiteSpeed の設定
今回設定した中で、ここが一番ハマりました。参考にしたサイトでは standalone-signaling ディレクトリを起点に Proxy 設定を入れていましたが、OLS の Web Socket Proxy が上手くいかなかったため、ドメイン直下で設定しました。
バーチャルホストにサブドメインを追加
高性能バックエンド用のサブドメインとして、hpb.example.com を追加します。
OLS の管理画面から、新しいバーチャルホストを追加し、リスナーのバーチャルホストマップに追加します。
- 基本
- バーチャルホスト名: hpb.example.com
- Virtual Host Root: /var/www/$VH_NAME
- 設定ファイル: $SERVER_ROOT/conf/vhosts/$VH_NAME/vhconf.conf
- 一般
- Document Root: $VH_ROOT
- ドメイン名: $VH_NAME
SSL 秘密鍵 & 証明書の設定も行っておきましょう。

外部アプリにシグナリングサーバーを追加
追加したバーチャルホストの外部アプリに、シグナリングサーバーを追加します。
- タイプ: Web サーバー
- 名前: Signaling
- アドレス: 127.0.0.1:8080

Rewrite ルールを追加
追加したバーチャルホストの Rewrite ルールを追加します。
- Rewrite 制御: はい
- Rewrite ルール
- RewriteCond %{REQUEST_URI} !^/.well-known/(acme-challenge|pki-validation)/
- RewriteRule ^/(.*) http://Signaling/$1 [P,L]
- Header set Host %{HTTP_HOST}
- Header set X-Real-IP %{REMOTE_ADDR}
- Header set X-Forwarded-For %{HTTP_X_FORWARDED_FOR}

Web Socket Proxy を追加
追加したバーチャルホストに Web Socket Proxy を追加します。
- URI: /spreed
- アドレス: 127.0.0.1:8080

以上で OLS の設定は完了です。緩やかな再起動をして、設定を反映させてください。
Nextcloud Talk に設定を反映
Nextcloud に管理者でログインし、設定画面から「管理」>「トーク」を開きます。
高性能バックエンド
- 高性能バックエンド URL: wss://hpb.example.com
- 共有秘密鍵:(HPB の共有秘密鍵)
- SSL 証明書を検証する: チェックする
共有秘密鍵には、Signaling の設定ファイル(/etc/signaling/server.conf)に記載された、backend-1 の secret を入力します。

正しく設定されるとステータスが「OK」になります。
STUN/TURN サーバー
- STUN サーバー: hpb.example.com:3478
- TURN サーバー:
- turn: hpb.example.com:3478(UDP と TCP)
- turns: hpb.example.com:5349(TCP のみ)
TURN サーバーシークレットには、coTURN の設定ファイル(/etc/coturn/turnserver.conf)に記載したものを入力します。

TURN サーバーの設定欄の右に緑のチェックマークが付けば、正しく設定されています。
ビデオ通話の検証
テスト用に 6 アカウントを用意してグループを作成、ビデオ通話の検証を行ないました。
PC のブラウザから 3 回線(光回線)、iPhone の Nextcloud Talk アプリ から 3 回線(モバイル通信:Wi-Fi オフ)の合わせて 6 人でビデオ通話を行いましたが、カクついたりすることも無く非常にスムーズでした。
ConoHa VPS 2G プランでも余裕で動きましたので、小規模の運用なら全く問題ないと思います。
参考にしたサイト

コメント