Tech

【OSSでWiki構築】第3回(環境構築編 トラブルシューティング)

最終更新:2026.03.23

はじめに

【OSSでWiki構築】第2回(環境構築編)」に記載された手順に至るまでに遭遇した、様々なエラーとその解決策をまとめたものです。

エラーは失敗ではなく、システムへの理解を深めるための最高のヒントです。各エラーから得られた学びを共有します。

問題1: Docker Hubの認証エラー

発生した事象

docker compose up -d を初めて実行した際、イメージのダウンロードに失敗し、以下のエラーが表示された。

Error response from daemon: authentication required - email must be verified before using account

原因の分析

このエラーは、「Docker Hubのアカウント認証が完了していない」ことを意味します。Docker Desktopの利用にはDocker Hubへのログインが必要ですが、その際に登録したメールアドレスの本人確認が完了していないと、Docker Hub(Dockerイメージの公式保管庫)からイメージをダウンロードする権限が得られません。

解決策

  1. Docker Hubから送られてきている「Verify your email address」という件名のメールを探し、認証リンクをクリックする。
  2. もしメールが見つからない場合は、Docker Hub公式サイトにログインし、画面の案内に従ってメールアドレスの認証を完了させる。

学んだこと

Docker Desktopは、イメージをダウンロードするために認証済みのDocker Hubアカウントを必要とします。インストール直後は、まずメール認証を完了させることが重要です。

問題2: ポートの競合エラー

発生した事象

コンテナを起動しようとした際、以下のエラーでoutlineコンテナの起動に失敗した。

listen tcp 0.0.0.0:3000: bind: address already in use

原因の分析

PCのポート(ネットワークのドア)は、一つのアプリケーションしか使用できません。このエラーは、Outlineが使おうとした3000番ポートが、すでに他のアプリケーションによって使用されていたために発生しました。

解決策

  1. 以下のコマンドで、どのアプリケーションがポートを使用しているか特定する。 lsof -i :3000
  2. 特定したアプリケーションを停止する。
  3. (もし停止できない場合)docker-compose.ymlportsURLの設定を、3000から3001など、空いている別のポート番号に変更する。

学んだこと

ポートは排他的なリソースです。address already in useエラーが出た際は、lsofコマンドで競合しているプロセスを特定するのが定石です。

問題3: アプリケーションの必須設定(環境変数)の不足

発生した事象

コンテナは起動するものの、すぐに停止してしまう。ログを確認すると、以下のエラーが出力されていた。

ケースA: RedisのURLが未設定

REDIS_URL should not be empty

ケースB: データベースのSSL接続エラー

The database does not support SSL connections. Set the `PGSSLMODE` environment variable to `disable`

原因の分析

  • ケースA: 最近のOutlineのバージョンでは、キャッシュ用のデータベースとしてRedisが必須になっていましたが、当初のdocker-compose.ymlにその設定が含まれていませんでした。
  • ケースB: Outlineはデフォルトで安全なSSL(暗号化)通信でデータベースに接続しようとしますが、ローカルで立てたPostgreSQLはSSLに対応していませんでした。

解決策

docker-compose.ymloutlineサービスのenvironmentセクションに、不足している環境変数を追記する。

  • ケースA: redisサービスをdocker-compose.ymlに追加し、REDIS_URL: 'redis://redis:6379'outlineの環境変数に追加した。
  • ケースB: PGSSLMODE: 'disable'outlineの環境変数に追加し、SSLを使わないように指示した。

学んだこと

エラーログは解決策の宝庫です。 特にアプリケーション固有のエラーは、ログに原因や、時には解決策(今回の場合Set the 'PGSSLMODE' ...)が直接書かれていることがよくあります。エラーが出たら、まずはログを丁寧に読むことが解決への一番の近道です。

問題4: ブラウザでの接続拒否と強制HTTPS化

発生した事象

  • 全てのコンテナが(healthy)状態で正常に起動しているにも関わらず、ブラウザでhttp://localhost:3000にアクセスできない (ERR_CONNECTION_REFUSED)。
  • URLが自動的にhttps://localhostに書き換わってしまう。
  • 別のブラウザや、http://127.0.0.1:3000でアクセスしても解決しない。

原因の分析

これは、Outlineアプリ自身が送ってくるHSTS (HTTP Strict Transport Security) ヘッダーが根本原因でした。

  1. 一度でもアクセスを試みると、Outlineがブラウザに対し「今後localhostへのアクセスは、絶対にHTTPSを使いなさい」という強力な指示を送ります。
  2. ブラウザはその指示を忠実に記憶し、以降のhttp://localhostへのアクセスをすべて強制的にhttps://localhostにリダイレクトしてしまいます。
  3. しかし、こちらの環境にはHTTPSで応答する準備がなかったため、接続エラーとなっていました。

この指示はブラウザの深いレベルで記憶されるため、通常のキャッシュクリアでは解決しませんでした。curl -v http://localhost:3000コマンドで通信内容を直接確認したところ、Strict-Transport-SecurityヘッダーとLocation: <https://localhost/というリダイレクト指示が返ってきており、これが決定的な証拠となりました。>

解決策

この複合的な問題を解決するため、以下の段階的な対策を実施しました。

  1. localhostの回避: HSTSの記憶が染みついたlocalhostを避けるため、hostsファイルを編集し、127.0.0.1outline.testという新しい名前を付けました。
  2. ローカルHTTPS環境の構築: OutlineがHTTPSを強く要求するため、リバースプロキシであるCaddyを導入し、ローカルでHTTPS通信を可能にしました。
  3. Caddyの設定: Caddyが外部の認証局に証明書を申請しに行ってしまうエラーを解決するため、Caddyfiletls internalを追記し、自家製の証明書を使うように指示しました。

補足:なぜ localhost ではなく outline.test を使ったのか?

このトラブルシューティングの過程で、 outline.test というカスタムドメインを導入しました。これは、localhost という名前に HSTS の記憶が染みついているという仮説に基づき、それを回避するための診断的なステップでした。

しかし、最終的な学びとして、Caddy によるローカル HTTPS 環境さえ用意すれば、HSTS が要求する https:// の条件を満たすことができると分かりました。

※事実、次回の「認証基盤編」では、Google の制約によって localhost を使う必要が出てきましたが、Caddyのおかげで https://localhost として問題なく動作させることができました。

つまり、Caddy を導入するという前提に立てば、localhost のままでもローカル HTTPS 環境を構築し、この問題を解決することは可能だったと言えます。outline.test への移行は、問題を切り分けるための有効な「回り道」でした。