Win11 + LM Studio + Open WebUI + SearXNG でローカルLLMにWeb検索させる(内蔵Web Loaderで安定運用)
※自分用のメモです。参考程度にしてね。
目的
- LM Studio(ローカルLLM)を Open WebUI から使う
- Web検索は SearXNG を使い、回答に検索結果(本文抽出済み)を混ぜる
- external Web Loader(例:host.docker.internal:3002)に依存せず、Open WebUI の内蔵 Web Loader で本文抽出まで完結させる
この手順の前提(固定値)
- OS: Windows 11
- Docker: Docker Desktop(Linux containers)
- Open WebUI:
ghcr.io/open-webui/open-webui:0.8.3(※:mainは使わない) - Open WebUI:
http://localhost:3000/ - SearXNG:
http://localhost:8080/ - LM Studio Local Server:
http://127.0.0.1:1234 - LM Studio モデル: Qwen2.5 32B Instruct(API Model Identifier:
qwen2.5-32b-instruct)
チェックリスト(ここだけ見れば動く)
- Open WebUI は 0.8.3 固定(main禁止)
-
Open WebUI の永続化 volume は
open-webui:/app/backend/data -
SearXNG の JSON API は 200 /
application/json -
Open WebUI の Web Search:
- Engine = SearXNG
- Query URL =
http://host.docker.internal:8080/search?q=<query>&format=json
-
Open WebUI の Web Loader:
- Engine = Internal
- External Web Loader URL は 空(3002は使わない)
-
Open WebUI → LM Studio は
http://host.docker.internal:1234/v1
1. LM Studio(OpenAI互換API)の場所(UI)
LM Studio で以下を確認します。
- 左メニュー → Developer → Local Server
- 上部の Reachable at: が
http://127.0.0.1:1234になっていること - 「Loaded Models」に
qwen2.5-32b-instructが READY で載っていること
Windows上は
http://127.0.0.1:1234、Dockerコンテナからはhttp://host.docker.internal:1234/v1を使います。
2. SearXNG(JSON API有効)を構築
作業ディレクトリ例:C:\Users\<you>\Documents\docker\searxng
2.1 docker-compose.yml(/etc/searxng を named volume 永続化)
docker-compose.yml を作成します。
services:
searxng:
image: searxng/searxng:latest
container_name: searxng
restart: unless-stopped
ports:
- "8080:8080"
environment:
- SEARXNG_SECRET=${SEARXNG_SECRET}
volumes:
- searxng_config:/etc/searxng
volumes:
searxng_config:
2.2 .env(secret_key対策)
同じフォルダに .env を作成します。
SEARXNG_SECRET=ここに長いランダム文字列
例(PowerShell):
[guid]::NewGuid().ToString("N")
2.3 settings.yml(json出力を許可)
PowerShell で settings.yml を作成します。
@"
use_default_settings: true
search:
formats:
- html
- json
"@ | Set-Content -Encoding utf8 .\settings.yml
起動&反映:
docker compose up -d
docker cp .\settings.yml searxng:/etc/searxng/settings.yml
docker restart searxng
2.4 SearXNG 動作確認
JSON が 200 で返ることを確認します。
curl.exe -sS -D - -o NUL "http://localhost:8080/search?q=test&format=json" | Select-String -Pattern "^HTTP/|^content-type:"
期待:
HTTP/1.1 200content-type: application/json
3. Open WebUI(0.8.3固定 + 永続volume固定)で起動
3.1 永続volume作成
docker volume create open-webui
3.2 Open WebUI 起動(0.8.3)
docker run -d --name open-webui --restart unless-stopped `
-p 3000:8080 `
-v open-webui:/app/backend/data `
ghcr.io/open-webui/open-webui:0.8.3
3.3 起動確認(ポート/volume)
docker inspect open-webui --format "Ports={{json .HostConfig.PortBindings}}`nMounts={{json .Mounts}}"
成功条件:
-
HostPortが3000 -
MountsにName: open-webuiとDestination: /app/backend/data
4. Open WebUI の設定(UI)
ブラウザで http://localhost:3000/ を開き、管理画面で設定します。
4.1 LM Studio 接続(OpenAI互換)
- Base URL:
http://host.docker.internal:1234/v1 - Model:
qwen2.5-32b-instruct
4.2 Web検索(SearXNG)
- Enable Web Search: ON
- Web Search Engine: SearXNG
- SearXNG Query URL:
http://host.docker.internal:8080/search?q=<query>&format=json
4.3 Web Loader(重要:Internal)
- Web Loader Engine: Internal
- External Web Loader URL: 空
- External Web Loader API Key: 空
Web Loader が external のまま
host.docker.internal:3002を指していると、本文抽出がConnection refusedで全滅します。
5. 疎通確認(Open WebUI コンテナ内 → SearXNG)
wget が無い環境があるため、python で確認します。
docker exec -it open-webui sh -lc "python3 - << 'PY'
import urllib.request, json
url='http://host.docker.internal:8080/search?q=test&format=json'
with urllib.request.urlopen(url, timeout=20) as r:
data=json.loads(r.read().decode('utf-8','replace'))
print('status ok; number_of_results=', data.get('number_of_results'), 'len(results)=', len(data.get('results') or []))
PY"
6. 成功判定(ログ)
Open WebUI のログを確認します。
docker logs -f open-webui
成功の目安:
-
Fetching pages: ...(本文取得できている) -
embeddings generated ...(RAG投入できている) -
query_doc:result ... source: https://...(検索結果がRAGに載っている)
トラブルシュート
A) host.docker.internal:3002 Connection refused
原因:Web Loader が external のまま 3002 に依存している
対策:Web Loader Engine を Internal に戻し、External URL を空にする
B) Open WebUI が初期セットアップ画面になる(ユーザーが消えたように見える)
原因:/app/backend/data が別volumeを掴んでいる
対策:docker inspect open-webui で Mounts の Name が open-webui か確認
C) SearXNG の /search?...&format=json が 403
原因:settings.yml の search.formats に json が無い
対策:formats: [html, json] にして再起動