2026年9月6日日曜日

Docker desktopで Open WebUI を立てたら「無限リロード」にハマった記録

 はじめに

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つが、今回の答えでした。