日本語 | English
LobeHub を自己ホストするための docker-compose 構成です。
本家 LobeHub の deploy / production 系構成を土台に、認証、監視、検索、オブジェクトストレージを外出しして運用しやすくしたリポジトリです。
この README は次の 2 つを両立するように整理しています。
- 初めて触る人が「何をどう起動すればよいか」を迷わない
- 慣れている人が「必要な設定や運用コマンド」にすぐ飛べる
- 最初に読む場所
- この構成で動くもの
- 5 分で始める
- セットアップモード
- 起動パターン
- よく使う確認コマンド
- スクリプト一覧
- 運用シナリオ別の使い方
- 主要ファイルとディレクトリ
- 主要な環境変数
- 認証とユーザー運用
- 監視構成
- 永続化とデータ保存先
- リセット方針
- 既知の注意点
最短で把握したい人はここだけ見れば大丈夫です。
- まずは 5 分で始める
- SearXNG の使い方を選ぶなら 起動パターン
- 運用スクリプトを探すなら スクリプト一覧
- ユーザー管理まわりを見るなら 認証とユーザー運用
- 消してよいデータ範囲を確認するなら リセット方針
このリポジトリの構成要素は次のとおりです。
| 項目 | 採用コンポーネント | 役割 |
|---|---|---|
| アプリ本体 | LobeHub | チャット UI / モデル呼び出し |
| 認証 | Casdoor | SSO / ユーザー認証 |
| DB | PostgreSQL (ParadeDB) | LobeHub / Casdoor の永続データ。全文検索に ParadeDB (pg_search) 拡張を使用 |
| キャッシュ | Redis | セッション / キャッシュ |
| オブジェクトストレージ | RustFS | S3 互換ストレージ |
| 検索 | SearXNG | Online Search の検索バックエンド |
| Web クローラ | Browserless | Online Search のクローラバックエンド(モダンページのレンダリング) |
| 監視 | Grafana / Prometheus / Tempo / OTel Collector | メトリクス / トレース可視化 |
| 公開経路 | Cloudflared | Cloudflare Tunnel 経由の公開 |
この構成の特徴:
- LobeHub のメールアドレス / パスワード登録は無効で、Casdoor を認証基盤として使います
- MinIO ではなく RustFS を使います
- 永続化は Docker named volume ではなく、基本的にホスト側ディレクトリへ bind mount します
with-searxngprofile により、内蔵 SearXNG と外部 SearXNG を切り替えられますwith-browserlessprofile により、内蔵 Browserless と外部 SaaS を切り替えられます
最低限、次が必要です。
dockerとdocker composebashpython3またはpythonopenssl
setup.sh は .env が無ければ .env.example から自動生成します。
- 初期設定を実行する
bash ./setup.sh- 構成を確認する
docker compose config- イメージを取得する
docker compose pull- 基盤サービスを起動する
docker compose up -d network-service postgresql redis rustfs rustfs-init tempo prometheus otel-collector casdoor
docker compose up -d searxng browserless
docker compose up -d lobe grafana- 状態を確認する
docker compose ps
docker compose logs -f lobe casdoor rustfs grafana tempo prometheus --tail 200| URL | 用途 |
|---|---|
http://localhost:3210 |
LobeHub |
http://localhost:8000 |
Casdoor 管理 UI / 認証 UI |
http://localhost:9001 |
RustFS Console |
http://localhost:3000 |
Grafana |
Browserless は内部ネットワーク専用(外部公開なし)で動かす前提です。デバッガ UI を開きたい場合は別途ポート転送を設定してください。
| ポート | 用途 |
|---|---|
3210 |
LobeHub |
8000 |
Casdoor |
9000 |
RustFS API |
9001 |
RustFS Console |
3000 |
Grafana |
4317 |
OTel Collector gRPC |
4318 |
OTel Collector HTTP |
5432 |
PostgreSQL |
6379 |
Redis |
setup.sh は、利用形態に応じて URL 類をまとめて整えるためのスクリプトです。
bash ./setup.shbash ./setup.sh --mode port --host 192.168.1.10 --yesbash ./setup.sh --mode domain --protocol https --app-domain lobe.example.com --casdoor-domain auth.example.com --rustfs-domain s3.example.com| モード | 想定用途 | 主に決まるもの |
|---|---|---|
local |
開発機や単体検証 | localhost ベースの URL |
port |
LAN 内や IP 直アクセス | http://<host>:port 形式の URL |
domain |
本番やリバースプロキシ前提 | 独自ドメインの URL |
.envが無ければ.env.exampleから生成するAUTH_SECRETなどのシークレットを必要に応じて生成するcasdoor/init_data.json.exmapleを元にcasdoor/init_data.jsonを生成するAUTH_CASDOOR_ISSUERやS3_ENDPOINTなどの URL を構成に合わせて更新するdocker compose configを使った構成検証を行う
.env の COMPOSE_PROFILES に with-searxng を含めます。
COMPOSE_PROFILES=with-searxng
SEARXNG_URL=http://searxng:8080起動:
docker compose up -d network-service postgresql redis rustfs rustfs-init tempo prometheus otel-collector casdoor
docker compose up -d searxng browserless
docker compose up -d lobe grafana.env の COMPOSE_PROFILES から with-searxng を外し、SEARXNG_URL を外部 URL へ変更します。
COMPOSE_PROFILES=
SEARXNG_URL=https://searx.example.com起動:
docker compose up -d network-service postgresql redis rustfs rustfs-init tempo prometheus otel-collector casdoor
docker compose up -d lobe grafana補足:
- 外部 SearXNG 側では
jsonフォーマットを有効にしてください SEARXNG_BASE_URLは SearXNG UI を別途公開する場合だけ実 URL に合わせて調整します
LobeHub の Online Search 機能は、検索結果のページ本文を抽出するためにクローラを使います。
既定では組み込み済みの簡易クローラ (naive) が動きますが、JavaScript レンダリングが必要なモダンサイトを取りたい場合は Browserless を併用すると成功率が上がります。
.env の COMPOSE_PROFILES に with-browserless を追加し、BROWSERLESS_URL を compose サービスに向けます。
COMPOSE_PROFILES=with-browserless,with-searxng
CRAWLER_IMPLS=naive,browserless
BROWSERLESS_URL=http://browserless:3000
BROWSERLESS_TOKEN=change_this_browserless_token
BROWSERLESS_BLOCK_ADS=1
BROWSERLESS_STEALTH_MODE=0起動:
docker compose up -d network-service postgresql redis rustfs rustfs-init tempo prometheus otel-collector casdoor
docker compose up -d searxng browserless
docker compose up -d lobe grafanacompose 内でコンテナを立てず、公式クラウド (https://chrome.browserless.io) や別ホストへ向ける場合は profile を外して URL / TOKEN だけ差し替えます。
# COMPOSE_PROFILES から with-browserless を外す
CRAWLER_IMPLS=browserless
BROWSERLESS_URL=https://chrome.browserless.io
BROWSERLESS_TOKEN=<your-api-token>補足:
- LobeHub 本体は BROWSERLESS_URL +
/contentエンドポイントへ POST リクエストを投げます。自己ホストする場合は v2 系イメージ (ghcr.io/browserless/chromium) を使ってください CRAWLER_IMPLSはカンマ区切りで複数指定できます。前から順にフォールバックされるためnaive,browserlessのように並べるのが無難です
docker compose config
docker compose psdocker compose logs -f lobe casdoor rustfs grafana tempo prometheus --tail 200curl http://localhost:9000/health
curl http://localhost:8000/.well-known/openid-configurationdocker compose exec searxng sed -n '1,120p' /etc/searxng/settings.yml# 内蔵コンテナを使っている場合。/content エンドポイントへ空リクエストを投げて応答を確認する。
curl -s -o /dev/null -w "%{http_code}\n" -X POST \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}' \
"http://localhost:3000/content?token=${BROWSERLESS_TOKEN}"運用スクリプトは scripts/ にあります。
「何に使うか」を最初に判断できるよう、用途別に表にまとめています。
| スクリプト | 役割 | 使うタイミング | 主な入力 | 代表例 |
|---|---|---|---|---|
setup.sh |
.env と Casdoor 初期データのセットアップ |
初回構築、URL 変更、再設定 | --mode, --host, --app-domain など |
bash ./setup.sh --yes |
original-setup.sh |
元の deploy 系セットアップスクリプト | 本家寄りの挙動を参照したい時 | 対話入力 | bash ./original-setup.sh |
scripts/export-master-model-settings.sh |
master ユーザーの provider / model 設定を SQL で抽出 | 現在設定の棚卸し、ENV 候補生成 | SOURCE_EMAIL |
SOURCE_EMAIL='0_0@kuwa.dev' bash scripts/export-master-model-settings.sh > scripts/out.jsonl |
scripts/copy-master-model-settings.sh |
master ユーザーの provider / model 設定を新規ユーザーへ複製 | 新規ユーザーを追加した直後 | SOURCE_EMAIL, HOURS_BACK |
SOURCE_EMAIL='0_0@kuwa.dev' HOURS_BACK=6 bash scripts/copy-master-model-settings.sh |
scripts/apply-generated-model-settings.sh |
DB コピーに加え、生成済み ENV を使って OpenAI 系の key_vaults を再反映 |
新規ユーザーへ実運用向け設定を寄せたい時 | SOURCE_EMAIL, HOURS_BACK |
SOURCE_EMAIL='0_0@kuwa.dev' HOURS_BACK=6 bash scripts/apply-generated-model-settings.sh |
scripts/backup-user-data.sh |
指定ユーザーの中核データを JSON へバックアップ | 移行前、削除前、復旧用取得 | SOURCE_EMAIL または SOURCE_USER_ID |
SOURCE_EMAIL='user@example.com' OUTPUT_FILE=./scripts/user-backup.json bash scripts/backup-user-data.sh |
scripts/restore-user-data.sh |
バックアップ JSON を既存ユーザーへ restore | ユーザー復旧、複製、移行 | TARGET_EMAIL または TARGET_USER_ID, BACKUP_FILE |
TARGET_EMAIL='user@example.com' BACKUP_FILE=./scripts/user-backup.json bash scripts/restore-user-data.sh |
scripts/delete-user.sh |
指定ユーザーを PostgreSQL から完全削除 | 退会対応、誤作成アカウント削除 | TARGET_EMAIL または TARGET_USER_ID, --confirm-delete |
TARGET_EMAIL='user@example.com' bash scripts/delete-user.sh --dry-run |
scripts/lib-lobehub-db.sh |
DB 系スクリプト共通関数 | 直接実行しない | なし | なし |
| ファイル | 役割 |
|---|---|
scripts/out.jsonl |
export-master-model-settings.sh の出力例 |
scripts/generated-model-provider.env |
out.jsonl から整理して配置する ENV 候補ファイル |
- 多くのスクリプトは
.envを読み込み、docker compose execで PostgreSQL へ接続します copy-master-model-settings.shとapply-generated-model-settings.shは、対象ユーザー側の provider / model 設定を上書きしますdelete-user.shはまず--dry-runで確認する前提ですrestore-user-data.shは対象ユーザーが LobeHub 上に既に存在している必要があります
- Casdoor でユーザーを作成する
- 対象ユーザーに一度ログインしてもらう
- master 設定をコピーする
SOURCE_EMAIL='0_0@kuwa.dev' HOURS_BACK=6 bash scripts/copy-master-model-settings.sh必要に応じて OpenAI 系 key_vaults まで合わせるなら:
SOURCE_EMAIL='0_0@kuwa.dev' HOURS_BACK=6 bash scripts/apply-generated-model-settings.shSOURCE_EMAIL='0_0@kuwa.dev' bash scripts/export-master-model-settings.sh > scripts/out.jsonlバックアップ:
SOURCE_EMAIL='user@example.com' OUTPUT_FILE=./scripts/user-backup.json bash scripts/backup-user-data.sh復元:
TARGET_EMAIL='user@example.com' BACKUP_FILE=./scripts/user-backup.json bash scripts/restore-user-data.shまず dry-run:
TARGET_EMAIL='user@example.com' bash scripts/delete-user.sh --dry-run問題なければ本実行:
TARGET_EMAIL='user@example.com' bash scripts/delete-user.sh --no-dry-run --confirm-delete| パス | 内容 |
|---|---|
docker-compose.yml |
実運用用 Compose 定義 |
.env.example |
環境変数テンプレート |
.env |
実運用用環境変数 |
setup.sh |
現在の merged 構成向けセットアップ |
original-setup.sh |
元の deploy 系セットアップ |
casdoor/init_data.json.exmaple |
Casdoor 初期データテンプレート |
casdoor/init_data.json |
Casdoor に読み込ませる初期データ |
bucket.config.json |
RustFS バケット公開設定 |
searxng/settings.yml |
SearXNG 設定 |
browserless/ |
(compose サービスのみ。永続化は named volume) |
grafana/ |
Grafana datasource / dashboard / data |
prometheus/ |
Prometheus 設定 / data |
tempo/ |
Tempo 設定 / data |
otel-collector/ |
OTel Collector 設定 |
postgresql/data |
PostgreSQL データ |
postgresql/update-extensions.sh |
ParadeDB / pgvector 拡張の自動更新スクリプト (マイグレーションコンテナが使用) |
redis/data |
Redis データ |
rustfs/data |
RustFS データ |
rustfs/logs |
RustFS ログ |
scripts/ |
運用補助スクリプト群 |
全部を読む必要はありません。まずは次の項目を押さえると運用しやすいです。
| キー | 用途 | 補足 |
|---|---|---|
APP_URL |
LobeHub の公開 URL | ブラウザから到達する URL |
INTERNAL_APP_URL |
コンテナ内部通信用 URL | Compose 構成で重要 |
AUTH_SSO_PROVIDERS |
SSO プロバイダー指定 | 現在は casdoor 前提 |
AUTH_DISABLE_EMAIL_PASSWORD |
LobeHub 直登録の無効化 | 1 で無効 |
AUTH_CASDOOR_ISSUER |
Casdoor issuer URL | OIDC の要 |
AUTH_CASDOOR_ID |
Casdoor client id | setup.sh がテンプレートから補完 |
AUTH_CASDOOR_SECRET |
Casdoor client secret | 同上 |
S3_ENDPOINT |
RustFS API 接続先 | LobeHub の保存先 |
RUSTFS_ACCESS_KEY |
RustFS アクセスキー | 通常は admin |
RUSTFS_SECRET_KEY |
RustFS シークレット | 初回で必ず見直す |
COMPOSE_PROFILES |
Compose profile 切り替え | with-searxng / with-browserless をカンマ区切りで指定 |
SEARXNG_URL |
検索バックエンド URL | 内蔵 / 外部どちらでも使用 |
CRAWLER_IMPLS |
有効化するクローラ実装(カンマ区切り) | naive,browserless など |
BROWSERLESS_URL |
Browserless API URL | 内蔵は http://browserless:3000 |
BROWSERLESS_TOKEN |
Browserless 認証トークン | 外部 SaaS 利用時は必須 |
BROWSERLESS_BLOCK_ADS |
広告ブロック有無 (1/0) |
1 推奨 |
BROWSERLESS_STEALTH_MODE |
ステルスモード有無 (1/0) |
反クローラ回避時に 1 |
GF_SECURITY_ADMIN_PASSWORD |
Grafana 管理者パスワード | 初期値のまま運用しない |
DEFAULT_FILES_CONFIG |
ナレッジ / メモリ埋め込みモデル | embedding_model=<provider>/<model> 形式。未設定時は openai/text-embedding-3-small にフォールバック |
モデル / provider 系の補足:
- サーバー全体で共有したい値は
.envに置きます - ユーザー単位の provider / model / keyVaults は DB に保存されます
- custom provider は
.envだけでは完全再現しづらいため、DB / UI / SQL ベースの運用が向いています - メモリ埋め込みモデルは
DEFAULT_FILES_CONFIGでのみ指定可能です。UI の「サービスモデル設定 → 記憶埋め込み」は LobeHub v2.2.x 時点ではサーバー側ルーティングに反映されないため、必ず環境変数で設定してください(詳細は 既知の注意点 を参照)
この構成では、LobeHub 側で新規登録しません。
- LobeHub の signup は無効
- Casdoor を ID Provider として利用
- ユーザー追加は Casdoor 側で実施
- Casdoor 管理画面でユーザーを作成する
- そのユーザーに LobeHub へログインしてもらう
- 必要なら
copy-master-model-settings.shなどでモデル設定を反映する
casdoor/init_data.json.exmaple には初期設定のテンプレートが含まれています。
setup.sh はこれを元に casdoor/init_data.json を生成します。
注意:
- seed 情報は本番投入前に必ず見直してください
- 既に
postgresql/dataが存在する場合、init_data.jsonの変更は Casdoor DB へ自動反映されません
| コンポーネント | 役割 |
|---|---|
network-service |
共有 network namespace とポート公開の集約 |
otel-collector |
LobeHub からの OTLP 受け口 |
tempo |
trace 保存 |
prometheus |
metrics 保存 |
grafana |
metrics / trace 可視化 |
- Grafana には Prometheus / Tempo datasource が登録済みです
- 初期状態ではダッシュボードは最小限なので、まずは Explore を使う前提です
otel-tracing-testprofile を使えば trace の導通テストもできます
| サービス | 保存先 |
|---|---|
| PostgreSQL | postgresql/data |
| Redis | redis/data |
| RustFS データ | rustfs/data |
| RustFS ログ | rustfs/logs |
| Grafana | grafana/data |
| Tempo | tempo/data |
| Prometheus | prometheus/data |
Ubuntu で RustFS を bind mount する場合、所有者を 10001:10001 にしないと Permission denied になることがあります。
sudo mkdir -p rustfs/data rustfs/logs
sudo chown -R 10001:10001 rustfs
sudo chmod -R 755 rustfs補足:
- Grafana / Prometheus / Tempo は compose 側で
user: "0"を指定し、権限エラーを避けています
次のディレクトリを削除すれば、それぞれのサービスは初期化されます。
postgresql/dataredis/datarustfs/datarustfs/logsgrafana/datatempo/dataprometheus/data
Browserless は named volume (
browserless-cache) のみ使用し、ホスト側ディレクトリは持ちません。キャッシュだけ消したい場合はdocker compose down -vまたはdocker volume rm lobehub_browserless-cacheを実行してください。
注意点:
- Casdoor も PostgreSQL を使っています
- そのため
postgresql/dataを丸ごと消すと Casdoor も消えます
つまり:
- 全消しするなら
postgresql/dataごと消す - Casdoor を残したいなら PostgreSQL 全削除はしない
- LobeHub だけ消したいなら
lobechatDB 単位での初期化が必要です
.envやscripts/generated-model-provider.envに実キーを書く場合は取り扱いに注意してください- seed 情報や初期シークレットは、本番運用前に必ず変更してください
- custom provider は
.envだけで完全再現しづらいため、DB / UI / SQL ベース運用の方が向いています - RustFS API は現在
9000前提の箇所があります - Cloudflared は
CLOUDFLARE_TUNNEL_TOKENを設定したあとに個別起動する前提です - Browserless は内部ネットワーク専用で動かす前提です。外部公開する場合はリバースプロキシと認証を必ず設定してください
- ParadeDB (
pg_search) 拡張は Docker イメージ更新時に自動追従しません。postgresql-extension-migratorサービスが起動時にALTER EXTENSION pg_search UPDATEを実行して最新化します。LobeHub v2.2.x はpg_searchv0.24.1+ で追加されたminimum_should_match引数を使うため、拡張が古いとerror: unboxing minimum_should_match_ argument failedでチャット不能になります。詳細は ParadeDB Upgrading を参照 - メモリ埋め込みモデルのプロバイダは
DEFAULT_FILES_CONFIGでのみ制御可能です。UI の「サービスモデル設定 → 記憶埋め込み」(systemAgent.userMemoryEmbedding) は LobeHub v2.2.x 時点ではサーバー側の embedding ルーティングに反映されません。DEFAULT_FILES_CONFIG未設定時はopenai/text-embedding-3-smallにフォールバックし、openaiプロバイダのkeyVaults.baseURLへリクエストが飛びます。OpenAI 互換ゲートウェイ (LiteLLM 等) に切り替える場合はDEFAULT_FILES_CONFIG=embedding_model=litellm/BAAI/bge-m3のように環境変数で明示指定してください
本番前に少なくとも次は確認してください。
- Casdoor の seed ユーザーや初期パスワードを変更した
.envのシークレット類を安全な値へ置き換えたAPP_URL/AUTH_CASDOOR_ISSUER/S3_ENDPOINTが実際の公開構成と一致している- SearXNG を内蔵で使うか外部で使うか決めた
- Browserless を内蔵で使うか外部 SaaS で使うか、
BROWSERLESS_TOKENを設定した - 必要なら Grafana の初期ダッシュボードを追加した