【OSSでWiki構築】連載記事一覧
第1回
第2回(環境構築編)
第3回(環境構築編 トラブルシューティング)
第4回(Google OAuth編)
第5回(Google OAuth編 トラブルシューティング)
第6回(アクセス制御編)
第7回:アクセス制御編 トラブルシューティング ※本記事
1. はじめに
このドキュメントは、「第6回:アクセス制御編 」を進める過程で実際に発生した問題と、その解決に至るまでのプロセスを記録したものです。
エラーは失敗ではなく、システムへの理解を深めるための最高のヒントです。エラーから得られた学びを共有します。
ケーススタディ1:「Dockerデーモン」への接続エラー
発生した事象
docker compose up -dコマンドを実行したところ、コンテナが起動せず、以下のエラーが表示された。
unable to get image ... Cannot connect to the Docker daemon ... Is the docker daemon running?
原因の分析
Docker daemon(デーモン)とは、Dockerの「現場監督」にあたる中心的なプログラムです。私たちがターミナルで打つコマンド(指示書)を受け取り、コンテナの起動や管理といった実作業を行います。
このエラーは、PCを再起動したり、Dockerをしばらく使っていなかったりしたために、Docker Desktop アプリケーション自体が起動していなかった(=現場監督が出勤していなかった)ことが原因でした。
解決策
- Finderの「アプリケーション」フォルダから、Docker Desktop(クジラのアイコン)を起動する。
- PCのメニューバーのアイコンが静止し、現場監督の準備が完了するのを待つ。
- 再度、ターミナルで
docker compose up -dを実行する。
学び
Dockerのコマンド(CLI)は、それを実行するDockerデーモン(Docker Desktopアプリ)が裏側で起動していることが大前提です。Is the docker daemon running?という親切なエラーメッセージは、まずDocker Desktopアプリの起動状態を確認すべきというサインです。
ケーススタディ2:「メンバー招待」のメールが送信されない
発生した事象
Outlineの+ Invite people...機能で、役割を指定して新しいユーザー(別アカウント)を招待したが、招待メールが受信トレイにも迷惑メールにも届かなかった。
原因の分析
私たちのOutlineコンテナはlocalhost(自分のPC)という隔離された環境で動いています。それ自体には、インターネットの世界にメールを送信するための「郵便局」の機能(SMTPサーバー)が設定されていません。そのため、Outlineは「招待した」という記録をデータベースに残すことはできても、手紙(招待メール)を外部に発送することができませんでした。
解決策
これはエラーではなく、ローカル環境における正常な(想定通りの)動作です。メールがなくても、招待プロセスをシミュレートすることで解決しました。
- GCP(用心棒)のリストに追加: Google Cloudの「テストユーザー」リストに、招待したアカウントのメールアドレスを手動で追加する。
- 本人が訪問: 招待されたアカウントで、シークレットブラウザから
https://localhostにアクセスし、Googleログインを行う。 - 登録完了: Outlineは、メールは見ていないものの、本人確認(Googleログイン)ができ、データベース内の招待リストにも名前があるため、招待時に指定された役割(例:
Viewer)で正しくユーザーを登録しました。
学び
localhost環境では、メール送信、決済、外部API連携など、インターネットへの出口が必要な機能はデフォルトでは動作しません。このような場合、機能が動かないことを前提に、そのプロセスをどうシミュレートしてテストするかを考えることが重要です。
ケーススタディ3:コレクション作成時の「Network error」(SSL証明書の自動更新)
発生した事象
Step1とStep2を夜に行い、翌朝にStep3の「新しいコレクションの作成」を試みたところ、ブラウザにA network error occurredというエラーが表示され、作成に失敗した。
原因の分析
これは、Caddy(SSL執事)の非常に優れたセキュリティ機能が正常に作動した結果でした。
- ログの確認:
docker compose logs -f outlineとdocker compose logs -f caddyの両方を監視しても、コレクション作成時にログが一切動かなかった。これは、サーバー側(コンテナ)の問題ではなく、ブラウザ(クライアント)側がリクエストの送信を拒否していることを示していました。 - 原因の特定: Caddyは
tls internal(自家製証明書)を使う際、セキュリティ訓練(シミュレーション)のために、意図的に賞味期限の短い(例: 12〜24時間)SSL証明書を発行します。 - 時間経過: 私たちが作業を翌日に持ち越したため、私たちが寝ている間に、Caddyは古い証明書を新しい証明書に自動更新していました。(
caddyのログにcertificate renewed successfullyの記録が残っていました) - ブラウザの混乱: ブラウザは、昨夜のログイン時に記憶した「古い証明書(身分証A)」を期待して接続しにいきました。しかし、Caddyが「新しい証明書(身分証B)」を提示したため、ブラウザは「身分証が違う!なりすまし攻撃かもしれない!」と判断し、安全のために一切の通信を遮断しました。これが「Network error」の正体でした。
解決策
この「身分証の不一致」による混乱を、サーバー側とブラウザ側の両方で解消しました。
- サーバー側リセット:
docker compose downとdocker compose up -dでコンテナを再起動し、Caddyに「新しい身分証B」を持って待機させた。 - ブラウザ側リセット:
https://localhostのタブで、スーパーリロード(Cmd + Shift + R)を実行し、ブラウザに「古い身分証Aの記憶」を強制的に忘れさせた。 - 信頼の再構築: 再度表示された「保護されていない通信」の警告画面で、
localhostへのアクセスを許可し、ブラウザに「これからはこの新しい身分証Bを信頼しなさい」と教えた。
学び
ローカルHTTPS環境では、Caddyのようなツールがセキュリティ訓練のために証明書を短期間で自動更新することがあります。もし翌日などに突然「ネットワークエラー」が発生した場合、この「証明書の不一致」を疑うべきです。解決策は、サーバー再起動と「スーパーリロード」によるブラウザのSSLキャッシュの強制クリアです。
前の記事:第6回(アクセス制御編)
次の記事:準備中
【OSSでWiki構築】連載記事一覧
第1回
第2回(環境構築編)
第3回(環境構築編 トラブルシューティング)
第4回(Google OAuth編)
第5回(Google OAuth編 トラブルシューティング)
第6回(アクセス制御編)
第7回:アクセス制御編 トラブルシューティング ※本記事