概要:

Nextcloudアップデート後に出るようになった

高性能バックエンドが構成されていません - 高性能バックエンドなしでNextcloud Talkを実行すると、非常に小規模な通話 (最大2~3人の参加者)でのみ利用できます。複数の参加者との通話がシームレスに機能するようにするためには高性能バックエンドを設定してください。

このメッセージを対処するため、「高性能バックエンドサーバ」とやらをインストールすることにします。

当初はこれは考慮していませんでした(個人用のファイルサーバとして使っていたため)が、

「自分の信条を曲げてまでDockerを入れてしまった以上、こいつもDockerで入れる」

と“それはそれ、これはこれ/That's another matter entirely, chaps."の精神でインストールしていきます。

これの導入により、何が変わるのか?

接続の安定化・高速化です。

これまでPHP(Nextcloud本体)が行っていた「誰と誰をつなぐか」という重い処理(シグナリング)を、専用のGo言語プログラム(高性能バックエンド)が肩代わりします。これにより、通話開始までの時間が短縮され、サーバー全体の負荷が劇的に下がります。

環境

  • Nextcloud 32.0.3
  • PHP 8.3
    • PHP-FPM 8.3
  • MySQL 8.0
  • Apache 2.4

さっくりとした手順

  1. 【コマンドライン】(オプション)docker-composeをインストールします。
  2. 【コマンドライン】レット文字列を生成します。
  3. 【コマンドライン】Dockerファイルを作成します。
  4. 【コマンドライン】コンテナを起動します。
  5. 【コマンドライン】Apache設定ファイルを編集します。
  6. 【Webブラウザ】動作を確認します。
  7. 【Webブラウザ】Nextcloud管理画面を設定します。

(オプション)docker-composeのインストール

sudo aptitude install docker-compose

筆者の好みでaptitudeを用いています。

シークレット文字列を生成します。

openssl rand -hex 16

4accc25d95464f00a9537dc956bd5414といった文字列が出ます。これを以下「共有シークレット」と呼びます。

Docker設定ファイルを作成します。

任意のコンテナ設定ファイル群に以下を作成します。

mkdir -p /path/to/container/directory/nextcloud-signaling
cd /path/to/container/directory/nextcloud-signaling && pwd

このディレクトリに入り、ファイルを作っていきます。

※ドメイン名などは自分の環境に合わせましょう。※

  • server.conf
[http]
listen = 0.0.0.0:8080

[app]

debug = false

[sessions]

# 手順1で生成した文字列を使用 hashkey = [共有シークレット] blockkey = [共有シークレット]

[backend]

# Nextcloud本体のURL backend = https://hoge.example.com # Docker内部からホストへのSSL検証をスキップ (接続エラー回避のため必須) allowall = true # 手順1で生成した文字列を使用 secret = [共有シークレット]

[nats]

url = nats://nats:4222

[mcu]

# 現時点ではJanus(MCU)は使用しないため無効化 # type = janus # url = ws://127.0.0.1:8188

※ これらシークレット文字列は、別個にしておいた方がより安全です。

-docker-compose.yml

version: '3.6'

services:
  nats:
    image: nats:2.9
    restart: always

  signaling:
    image: strukturag/nextcloud-spreed-signaling:latest
    restart: always
    ports:
      - "127.0.0.1:8080:8080" # ホストのApacheからのみアクセス許可
    volumes:
      - ./server.conf:/config/server.conf
    depends_on:
      - nats
    extra_hosts:
      # Docker内部から hoge.example.com を解決するためにホストIPを指定
      - "hoge.example.com:172.17.0.1"

※重要: extra_hosts には ip addr show docker0 で確認したホストIP (例: 172.17.0.1) を記述します。

Dockerファイルを起動します。

cd /path/to/container/directory/nextcloud-signaling && pwd

念のため、先ほど作成したディレクトリにいることを確認してください。

  • コンテナ起動
sudo docker-compose up -d
  • コンテナ起動確認
sudo docker ps

STATUS が UPになっていれば問題なく起動できています。

Nextcloudのバーチャルサイトの編集

  • バーチャルファイルのバックアップ
sudo cp -pi /etc/apache2/sites-available/nextcloud.conf /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d)

.confやバックアップディレクトリは自分の環境に合わせます。

  • バーチャルファイルのバックアップ確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf

差分が無いことでバックアップを確認します。

  • ファイル編集

/etc/apache2/sites-available/nextcloud.conf を、任意の方法で編集します。(エディタという宗教問題が絡むため)

他のリダイレクト設定やセキュリティ設定(RewriteRuleなど)に干渉されないよう、<VirtualHost *:443> ブロック内のなるべく上の方に記述するのがコツです。

<VirtualHost *:443>
    # (その他既存の設定...)

    # ====================================================
    # Signaling Server 設定
    # ====================================================

    # 1. バックエンド(Docker)に正しいホスト名とプロトコルを伝える
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto "https"

    # 2. プロキシ設定
    # "upgrade=websocket" オプションにより、http/ws を自動判別してヘッダーを渡す
    ProxyPass "/standalone-signaling/" "http://127.0.0.1:8080/" upgrade=websocket
    ProxyPassReverse "/standalone-signaling/" "http://127.0.0.1:8080/"

    # ====================================================

    # ... (これ以降にDocumentRootやセキュリティ設定が続く) ...
  • 編集後の差分確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf

以下の差分を確認します。

+# ====================================================
+    # Signaling Server 設定
+    # ====================================================
+    # 1. バックエンド(Docker)に正しいホスト名とプロトコルを伝える
+    ProxyPreserveHost On
+    RequestHeader set X-Forwarded-Proto "https"
+
+    # 2. プロキシ設定
+    # "upgrade=websocket" オプションにより、http/ws を自動判別してヘッダーを渡す
+    ProxyPass "/standalone-signaling/" "http://127.0.0.1:8080/" upgrade=websocket
+    ProxyPassReverse "/standalone-signaling/" "http://127.0.0.1:8080/"
+    # ====================================================
+

設定反映

  • 整合性確認
sudo apache2ctl configtest

Syntax OKを確認します。

  • apache再開前確認
systemctl status apache2.service

active(running)を確認します

  • apache再開
sudo systemctl restart apache2.service
  • apache再開確認
systemctl status apache2.service

active(runnning)を確認します。

動作確認

ブラウザで、

https://hoge.example.com/standalone-signaling/api/v1/welcome

にアクセスし、{"nextcloud-spreed-signaling":"Welcome", ...}の表示が出ていればOKです。

Nextcoloud管理画面設定

Nextcloudに管理者ログインし、[管理設定] > [Talk] > [高性能バックエンド] を設定します。

  • 高性能バックエンドURL: https://hoge.example.com/standalone-signaling/
  • 共有シークレット: 手順1で生成した文字列
  • SSL証明書を検証する: チェックを入れる

設定後、「保存」ボタンをクリックします。 「OK: 実行中のバージョン: x.x.x~docker」 と表示されれば完了です。

FAQ

Q. Dockerを入れることでサーバそのものが高負荷になるということは?

A. むしろ逆で、サーバー全体の負荷は「劇的に下がります」。

  • これまで(高性能バックエンドなし):
    • Nextcloudの画面を開いている間、ブラウザは数秒おきに「着信はありますか?」「新しいチャットはありますか?」とサーバー(Apache/PHP)に聞きに行きます(ポーリング方式)。 そのたびに Apacheが動き、PHPが起動し、データベースに接続し… という重い処理が走っていました。これがサーバーを高負荷にする原因です。
  • これから(高性能バックエンドあり):
    • Docker(Go言語)が、ブラウザと「1本のパイプ(WebSocket)」を繋ぎっぱなしにします。 情報はパイプを通ってスッと届くため、「着信確認」のための無駄な処理がゼロになります。

Q. メモリは食いますか?

A. メモリは食いますが、CPUは休まります。

  • Dockerコンテナが常駐するため、約50MB〜100MB程度のメモリ を常に確保(占有)します。これは増えます。
  • しかし、上記の「無駄な確認作業」がなくなるため、CPUの利用率はガクンと下がります。 サーバーにとって一番きついのは「メモリを確保すること」ではなく「CPUをブン回すこと」なので、トータルではサーバーが楽になります。

もっとさっくり言うと:

  • 1. 以前(高性能バックエンドなし)
    • 動作: ブラウザが「ねえ、着信ある?」「ねえ、メッセージ来た?」と、数秒おきにApacheを叩き起こしていました。
    • 負荷: そのたびに、数十MBのメモリを使うPHPプロセス が起動し、データベースに接続し、確認して終了する…という「重い開け閉め」を繰り返していました。
  • 2. 現在(高性能バックエンドあり)
    • 動作: 今回導入した signaling コンテナ(7MB/筆者環境)が、ブラウザと細い糸電話(WebSocket)を繋ぎっぱなしにします。
    • 負荷: 何もなければただ待っているだけ(CPU 0.02%/筆者環境)。着信があった時だけ、「来たよ!」と一瞬で伝えます。

重たいApacheやPHPは、本当に必要な画面表示の時だけ働けば良くなったので、サーバー全体が静かになり、反応速度(レスポンス)が向上します。