Collabora Online 構築レポート
最新 Collabora は hirame (X58A-UD3R) の Docker container。 fabric (173.0.0.4/30) 経由で maguro NC と直結。 R640 経由を廃止しセキュリティ・性能・可用性を同時向上。
| 項目 | 値 |
|---|---|
| ホスト | hirame (X58A-UD3R) |
| 方式 | Docker container (collabora/code 25.04.9.4) |
| compose ファイル | /home/hirame/collabora/docker-compose.yml |
| ポート | 9980/tcp (Listen) |
| extra_hosts | cloud.k2-o.net:173.0.0.5 (maguro fabric直結) |
| SSL | termination は外側 nginx で実施 (内部は HTTP) |
version: '3'
services:
collabora:
image: collabora/code
container_name: collabora
restart: unless-stopped
ports:
- '9980:9980'
extra_hosts:
- 'cloud.k2-o.net:173.0.0.5' # ← maguro fabric直結 (2026-05-14)
environment:
- 'extra_params=--o:ssl.enable=false --o:ssl.termination=true'
- 'server_name=cloud.k2-o.net'
- 'aliasgroup1=https://cloud\.k2-o\.net:443'
- 'username=admin'
- 'password=<管理者パスワード>'
cap_add:
- MKNOD
| 項目 | 値 |
|---|---|
wopi_url |
http://173.0.0.10:9980 (NC → Collabora、 fabric経由) |
public_wopi_url |
https://cloud.k2-o.net (browser → Collabora 表示用) |
wopi_allowlist |
173.0.0.4/30, 173.0.0.8/30, 119.26.175.225 |
container → docker bridge → hirame eth → 173.0.0.9 (R640 fabric)
→ R640 nginx stream (SNI passthrough)
→ R640 VLAN30 (192.168.30.21)
→ maguro nginx (remote_addr = 192.168.30.21) ※ R640 出口 IF に置換される
新経路 (fabric 直結)
container → docker bridge → hirame eth → 173.0.0.5 (maguro fabric)
→ maguro nginx (remote_addr = 173.0.0.6 = hirame SM-fabric IF)
- 経路短縮 (3 ホップ → 1 ホップ): レイテンシ低下、 スループット向上
- セキュリティ強化: NC の wopi_allowlist から R640 SNI IP (192.168.30.21) を外せる。 外部から「SNI を装って WOPI を叩く」可能性を遮断
- R640 障害耐性: R640 が落ちても Collabora ⇄ NC は継続稼働
- 設計整合性: 内部通信は内部経路を通す素直な構成
# /etc/nginx/sites-enabled/cloud.k2-o.net (要点)
location /browser {
proxy_pass http://173.0.0.10:9980;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 36000s;
}
location /hosting/discovery { proxy_pass http://173.0.0.10:9980; ... }
location /hosting/capabilities { proxy_pass http://173.0.0.10:9980; ... }
location ^~ /cool/ {
proxy_pass http://173.0.0.10:9980;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 36000s;
}
location ^~ /index.php/apps/richdocuments/wopi/ {
# fabric経由のみ許可 (Collabora→NC コールバック)
allow 173.0.0.8/29;
allow 173.0.0.4/30;
allow 192.168.20.0/24;
allow 119.26.175.225;
deny all;
proxy_pass http://127.0.0.1:9080;
...
}
maguro から hirame fabric への 173.0.0.8/30 への route は netplan で永続化:
# /etc/netplan/00-supermicro.yaml
network:
ethernets:
SM-HIRAME-FAB:
match:
macaddress: "50:6b:4b:7f:0b:61"
addresses:
- "173.0.0.5/30"
routes:
- to: "173.0.0.8/30" # hirame R640-FAB range への片道route
via: "173.0.0.6"
# NC コンテナから Collabora へ到達確認
sudo docker exec compose-app-1 curl -s -o /dev/null -w '%{http_code}\n' http://173.0.0.10:9980/hosting/discovery
# → 200
# Collabora コンテナから NC へ
ssh root@173.0.0.10 'docker exec collabora curl -sk -o /dev/null -w "%{http_code} via %{remote_ip}\n" https://cloud.k2-o.net/status.php'
# → 200 via 173.0.0.5
# NC 側 discovery 再取得
sudo docker exec -u www-data compose-app-1 php occ richdocuments:activate-config
| 層 | 設定 | 方向 |
|---|---|---|
| A (Collabora側) | aliasgroup1=https://cloud\.k2-o\.net:443 |
NC ホスト名許可 |
| B (NC側) | wopi_allowlist |
Collabora 発信元IP許可 |
両方マッチしないと 「認証されていないWOPIホスト」 エラー。 NC nginx access.log で WOPI コールの status を確認 — 403 なら B層、 connect refused なら A層。
2026-05-14 までは extra_hosts: cloud.k2-o.net:173.0.0.9 (R640 fabric IP) だった。 これだと Collabora コンテナ → R640 SNI passthrough → maguro という遠回り経路で、 maguro 着信時の remote_addr が 192.168.30.21 (R640 VLAN30 IF) に置換される (stream module は TCP生proxy)。 結果として NC の wopi_allowlist に R640 SNI IP を入れる必要があり、 外部経路と内部経路の境界が曖昧に。 fabric直結化でクリーンに分離。
docker-compose up -d --force-recreate 時に KeyError: 'ContainerConfig'。 解決: docker-compose down → docker-compose up -d で fresh up。
WOPI 403 が出続けた時期 (2026-05-14 切替直前) の試行錯誤:
- R640 SNI passthrough の remote_addr 置換に気付くまで「DNS 解決の問題」と誤診断していた
wopi_allowlistに192.168.30.21を一時的に追加して開通 → 後で fabric 直結化に切替- nginx
sed -iでファイル全体置換するとlocation /の192.168.30.21も消えて、 LANクライアントが access forbidden になるトラブル → 行範囲スコープで限定削除すべし
hirame → R640 へ Collabora を移植、 hirame は poweroff
| 項目 | 旧 (hirame) | 新 (R640) |
|---|---|---|
| Collabora docker host | hirame 173.0.0.10 | R640 173.0.0.2 |
NC wopi_url |
http://173.0.0.10:9980 | http://173.0.0.2:9980 |
NC DocumentServerInternalUrl |
http://173.0.0.10:9980/ | http://173.0.0.2:9980/ |
| maguro nginx proxy | http://173.0.0.10:9980 | http://173.0.0.2:9980 |
| extra_hosts (container) | cloud.k2-o.net:173.0.0.5 | cloud.k2-o.net:173.0.0.1 |
| Collabora →NC callback src | 173.0.0.5 (maguro-hirame fabric) | 173.0.0.2 (R640-maguro fabric) |
1. DocumentServerInternalUrl は wopi_url とは別の設定
occ config:app:set richdocuments wopi_url ... だけだと不十分。 NC は capabilities fetch に DocumentServerInternalUrl を見る。 両方更新すべし。
occ config:app:set richdocuments wopi_url --value="http://173.0.0.2:9980"
occ config:app:set richdocuments DocumentServerInternalUrl --value="http://173.0.0.2:9980/"
2. NC wopi_allowlist と nginx allow は別物 — 両方更新必要
同じ「Collabora の発信元 IP を許可する」設定が NC アプリ層と nginx 層の二箇所にある。 片方だけだと、 nginx で 403 拒否 (Collabora → NC callback 失敗) → Collabora ログに WOPI::CheckFileInfo returned 403 (Forbidden)。
# NC layer
occ config:app:set richdocuments wopi_allowlist \
--value="173.0.0.0/30,173.0.0.4/30,173.0.0.8/30,119.26.175.225"
# nginx layer (cloud.k2-o.net の wopi location)
location ^~ /index.php/apps/richdocuments/wopi/ {
allow 173.0.0.0/30; # R640-maguro fabric ←追加忘れ注意
allow 173.0.0.4/30; # maguro-hirame fabric
allow 173.0.0.8/29; # R640-hirame fabric
...
}
3. sites-enabled がシンボリックリンクでなく実ファイルのことがある
maguro の /etc/nginx/sites-enabled/cloud.k2-o.net は実ファイル。 sites-available 側を sed 編集しても反映されない。 ファイル属性を ls -la で必ず確認。
4. nginx backup ファイルを sites-enabled に置くと conflicting server_name で旧設定が勝つ場合あり
.bak 等のサフィックスを付けても nginx は読み込む (拡張子フィルタは無い)。 backup は必ず sites-available か別ディレクトリへ。
5. Collabora の aliasgroup1 env var は coolwsd.xml に反映されないことがある
起動スクリプトが --use-env-vars 経由で渡しても、 coolwsd.xml の alias_groups は mode="first" のまま。 結果として最初に接続したホストだけが許可され、 cloud.k2-o.net が拒否される。 extra_params で明示指定すること:
extra_params=--o:storage.wopi.alias_groups.mode=groups \
--o:storage.wopi.alias_groups.group[0].host=https://cloud\.k2-o\.net:443 \
--o:storage.wopi.alias_groups.group[0].host[@allow]=true
6. extra_hosts の IP は移植先サーバの fabric 接続先に合わせて変える
hirame で動かしてた時は cloud.k2-o.net:173.0.0.5 (maguro-hirame fabric)。 R640 へ移すと cloud.k2-o.net:173.0.0.1 (maguro-R640 fabric)。 docker-compose の extra_hosts セクションをコピペで持ってくると詰む。
7. Collabora の convert-to は POST API で別の allow リスト
PDF export 等で使う /lool/convert-to エンドポイントは net.post_allow.host で別途許可必要。 デフォルトは 127.0.0.1, ::1 のみ。 NC からの呼び出し src IP (fabric IP) を追加。
--o:net.post_allow.host[0]=127.0.0.1 \
--o:net.post_allow.host[1]=::1 \
--o:net.post_allow.host[2]=173.0.0.1
| 症状 | 原因層 | 確認コマンド |
|---|---|---|
| “ドキュメントの読み込みに失敗” + “Nextcloud Office が読み込めませんでした” | NC capabilities fetch 失敗 (Internal URL 設定 or Collabora 死亡) | occ richdocuments:activate-config で ✓ × の項目確認 |
| “認証されていないWOPIホストです” | Layer A (Collabora alias_groups) または Layer B (NC nginx 403) | Collabora docker logs で WOPI::CheckFileInfo returned XXX を確認。 403 ならB層 nginx、 alias_groups ログならA層 |
| ブラウザで Collabora UI ロード自体失敗 | maguro nginx の /browser proxy_pass 先が死んでる |
curl https://cloud.k2-o.net/browser/dist/cool.html で 502 → upstream 確認 |
| convert-to (PDF export) だけ失敗 | Collabora net.post_allow.host に NC src IP が無い |
Collabora docker logs で convert-to: Requesting address is denied: X.X.X.X |
- R640 self-test:
curl http://173.0.0.2:9980/hosting/capabilities→ JSON - maguro→R640 fabric:
curl http://173.0.0.2:9980/hosting/capabilities(maguro から) → 同じ JSON - Collabora container 内DNS:
docker exec collabora getent hosts cloud.k2-o.net→ 173.0.0.1 - Collabora→NC:
docker exec collabora curl -sk https://cloud.k2-o.net/status.php→ 200 - 外部経由 Collabora UI:
curl https://cloud.k2-o.net/browser/dist/cool.html→ 200 - 外部経由 discovery:
curl https://cloud.k2-o.net/hosting/discovery→ 200 + WOPI XML - NC capabilities 再取得:
occ richdocuments:activate-config→ 全 ✓ - ブラウザで NC 開いて .docx 編集 → ✅
記録: コード君 (Claude Opus 4.7) / 2026-05-15 06:00 JST