2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ローカルLLMにWeb検索を持たせる:OpenWebUI + SearxNG 構築で詰まった全記録

2
Posted at

はじめに

ChatGPT や Perplexity のような「検索しながら答えてくれる AI」を、ローカルで・無料で・自分のデータを外に出さずに実現したい。そう思って調べると、Ollama + OpenWebUI + SearxNG という構成が定番として出てくる。

構成としてはシンプルで、ドキュメントを読めばなんとなく動きそうに見える。実際、コンテナを2つ立てて URL を設定するだけ、のはずだった。

ところが実際にやってみると、各コンポーネントの「デフォルトでオフになっている設定」が絶妙に噛み合っていて、何も考えずに繋ごうとすると各所でエラーになる。エラーのほとんどはメッセージだけでは原因が分からないタイプで、初見だとかなり時間を食う。

この記事では、構築手順とあわせて「ここで詰まった」というポイントを全部書いておく。同じ構成を試している人の時間を少しでも節約できれば。

環境は以下の通り。

項目 内容
マシン Mac mini (2024)
OS macOS Tahoe 26.3.1 (arm64)
CPU Apple M4 (10コア / 4.46 GHz)
メモリ 32 GB
コンテナ実行環境 Docker Desktop

構成

[OpenWebUI :3000] → [SearxNG :8080] → Web検索
      ↕
[Ollama(ホスト)]

OpenWebUI と SearxNG はそれぞれ独立した Docker コンテナで動かす。
Ollama はホストに直インストール済みの前提。

1. コンテナを起動する

OpenWebUI

docker run -d \
  -e WEBUI_WORKERS=2 \
  -p 3000:8080 \
  -v openwebui:/app/backend/data \
  --name openwebui \
  --restart always \
  ghcr.io/open-webui/open-webui:main

http://localhost:3000 でアクセスできれば OK。

SearxNG

docker run -d \
  -p 8080:8080 \
  --name searxng \
  searxng/searxng

http://localhost:8080 でアクセスして検索画面が出れば OK。

2. SearxNG の設定を変える(ここが最大の罠)

SearxNG はデフォルトで JSON フォーマットの API レスポンスが無効になっている。
そのまま OpenWebUI から叩くと、JSON を期待しているのに以下のエラーが返ってくる。

Forbidden
You don't have the permission to access the requested resource.

ブラウザで http://localhost:8080/search?q=test&format=json を叩いてみると一目瞭然。

コンテナに入って settings.yml を編集する

ここで最初にやりがちなミス。bashで入ろうとするとこうなる:

$ docker exec -it searxng /bin/bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory

SearxNG のイメージは Alpine ベースなので /bin/bash が存在しない。/bin/sh を使う:

docker exec -it searxng /bin/sh

入れたら settings.yml を編集する:

vi /etc/searxng/settings.yml

search: セクションに json を追加する:

search:
  formats:
    - html
    - json   # これを追加

保存して抜けたらコンテナを再起動:

docker restart searxng

確認

http://localhost:8080/search?q=test&format=json

JSON が返ってきたら成功。

3. OpenWebUI の Web 検索設定

OpenWebUI の管理画面から設定する。

設定 → ウェブ検索

項目
ウェブ検索 ON
ウェブ検索エンジン searxng
Searxng クエリ URL http://host.docker.internal:8080

localhost ではなく host.docker.internal を使う理由

OpenWebUI はコンテナの中で動いている。コンテナ内から localhost を叩いても、それはコンテナ自身の localhost であり、ホストマシンの 8080 には届かない。

Docker Desktop(Mac / Windows)では、ホストマシンを指すための特別なホスト名として host.docker.internal が用意されている。

✗  http://localhost:8080        → コンテナ自身を見に行く(つながらない)
✓  http://host.docker.internal:8080  → ホストの 8080 に届く

Linux + Docker Engine の場合は host.docker.internal が使えないケースがあるので注意(--add-host=host.docker.internal:host-gateway が別途必要)。


4. モデル設定で Web Search を有効化(見落としやすい)

SearxNG の URL を設定しただけでは Web 検索は動かない。モデルごとに Web Search を有効化する必要がある。

管理者パネル → モデル → 使用するモデルを選択(例:gemma4:latest

モデル設定画面を下にスクロールすると「デフォルト機能」というセクションがある。

デフォルト機能
☑ ウェブ検索    ☐ 画像生成    ☐ コードインタプリタ

ここの **「ウェブ検索」にチェックを入れて「保存して更新」**する。

デフォルトではオフになっているので見落としやすい。チャット画面で検索マークが表示されていても、このチェックがオフだと実際には検索が走らず、モデルの学習データの範囲でしか回答しない。

設定前は「今日のセキュリティニュースを教えて」と聞いても、学習データ時点の情報を返すだけだった(しかも「リアルタイム情報は持っていません」と言いつつそれっぽい回答を生成する、という挙動をする)。

5. 動作確認

今日のセキュリティニュースを教えて

SearxNG 経由でリアルタイムに検索した結果を元に回答が返ってくれば完成。

まとめ:詰まりポイント一覧

症状 原因 対処
docker exec /bin/bash が失敗する Alpine イメージに bash がない /bin/sh を使う
format=json で 403 Forbidden JSON API がデフォルト無効 settings.ymlformats: [html, json] を追加
OpenWebUI から SearxNG につながらない コンテナ内の localhost はホストではない URL を host.docker.internal:8080 にする
設定したのに検索が動かない モデルごとの「デフォルト機能」がオフ 管理パネル → モデル → デフォルト機能 → ウェブ検索をオン

おわりに

構成自体はシンプルだが、「Alpine に bash はない」「Docker コンテナ内の localhost はホストではない」「SearxNG の JSON API はデフォルト無効」「モデルごとに Web Search を有効化しないといけない」という4つの落とし穴が重なると地味に時間を食う。

特に最後のモデル設定は、グローバルの Web 検索設定とは別に存在するので、「設定したのに動かない」という状況になりやすい。同じところで詰まった人の助けになれば。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?