はじめに
Docker desktop を使って Open WebUI をローカルに立ち上げました。
以下の流れで行いました。
・Docker desktop 起動
・環境構築用のフォルダをデスクトップに作成
・このフォルダに、docker-compose.yml を保存
・ターミナルを立ち上げ、このフォルダに移動、docker-compose up -d を実行
・http://localhost:3100で、Open WebUI が立ち上がれば成功
「コンテナは Up になっている。ログにも致命的なエラーはない。なのにブラウザを開くとページが無限にリロードを繰り返して、何も表示されない。」
そしてある瞬間、なぜか突然、まともに動いた。
この記事では、あの「突然動いた」の正体を、ログを見ながら紐解いていきます。同じ現象で詰まっている方の参考になれば。
現象:起きていたこと
ブラウザで http://localhost:3100 を開くと、リロードが止まらない
サーバーログに大量の 404 Not Found が流れ続ける
そのあと 500 Internal Server Error が混ざる
Docker のコンテナ状態は Up(緑)
ログが教えてくれたこと
流れるログの、いちばん怪しいのはここです。
"GET /_app/version.json HTTP/1.1" 200
"GET /_app/immutable/chunks/DI6U-d8h.js HTTP/1.1" 404
"GET /_app/immutable/chunks/D4rfk4Lu.js HTTP/1.1" 404
"GET /_app/version.json HTTP/1.1" 200
ポイントは、version.json は 200(成功)なのに、特定の .js ファイルだけが 404(存在しない) ということ。
つまりサーバーは生きているのに、「その JS ファイルがまだコンテナの中に存在していない」 ということです。
正体:「ファイル展開」と「モデルダウンロード」が完了していなかっただけ
Open WebUI は起動時に、フロントエンドの静的ファイルを配置し、さらに Hugging Face から embedding モデル(all-MiniLM-L6-v2)をダウンロードします。
この準備が完了する前にブラウザがリクエストしてくると、
ファイルがまだ展開済みでない → 404
DB や初期化が途中で飛ぶ → 500
ブラウザは「エラー!」と判定して再度読み込む → 無限リロード
という悪循環に陥ります。
さらに、このモデルのダウンロードは未認証リクエストだと Hugging Face にレート制限されて速度が激減します。私のログでは
Fetching 30 files: 23% | 7/30 [00:00<00:02, 16.44it/s]
Fetching 30 files: 30% | 9/30 [15:20<46:40, 133.38s/it] ← ここから速度崩壊
と、いきなり速度が 2桁秒/ファイル になっていました。
つまり「突然動いた」の正体は、この背景のダウンロード・展開が、ようやく完了してファイルが揃った、ということでした。 設定が“奇跡的に正しかった”のではなく、時間とリソースをくれたことが効いたんです。
じゃあどうすればいいか(推奨設定)
最小構成だと初回が非常に不安定なので、実際には以下を強化することを強くおすすめします。
最小構成(動くが、初回が不安定)
yamlの内容
services:
openwebui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
ports:
- "3100:8080"
volumes:
- ./openwebui-data:/app/backend/data
environment:
- WEBUI_AUTH=False
restart: always
※末尾に誰も使わない volumes: open-webui: があると、意味のない named volume が作られるので削除しています。
強化構成(ここが本題:HF_TOKEN + キャッシュ永続化)
yamlの内容
services:
openwebui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
ports:
- "3100:8080"
volumes:
- ./openwebui-data:/app/backend/data
- ./huggingface-cache:/root/.cache/huggingface # モデルのキャッシュをホストに保持
environment:
- WEBUI_AUTH=False
- HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxx # Hugging Face のトークン
- HF_HOME=/root/.cache/huggingface
restart: always
この2つの追加が何を変えるか:
追加 効果
HF_TOKEN 認証付きリクエストになるためレート制限が緩み、ダウンロードが速くなる
キャッシュ用 volume 初回だけダウンロードし、以降は再ダウンロードしない(起動が飛躍的に速くなる)
HF_TOKEN は Hugging Face の Access Tokens で Read 権限で発行できます。
チェックリスト(また詰まった時のために)
docker logs -f openwebui を見て、.js の 404 が流れていないか確認
Docker Desktop の Resources → Memory が 8GB〜16GB あるか(少なすぎると展開に失敗する)
初回起動は数分〜十数分、放置する(ダウンロードの完了を待つ)
ブラウザはシークレット窓か**強制リロード(Cmd+Shift+R / Ctrl+Shift+R)**で確認
それでも 500 が出るなら docker-compose down → ./openwebui-data 削除 → docker-compose up -d で DB を再生成
おわりに
「コンテナが Up = アプリの準備完了」とは限らない、という今回の教訓。
ログの 404(ファイルがまだない) と 500(処理が途中で壊れる) を見分けるだけで、「故障した」のではなく「準備中」と判断できて、無駄な再インストールを避けられます。
私の“突然動いた”は、魔法ではなかった。
待てたこと、メモリを割けたこと、そして次回の自分を救うためにキャッシュを永続化したこと。
その3つが、今回の答えでした。