生成AIを社内で使い始めてから、ツール自体は便利になった。
でも、その裏で 新しい管理地獄 が静かに始まっていた。
ユーザー管理、権限管理、アカウント削除、パスワード忘れ対応。
正直、「これ、楽になるどころか増えてないか?」というのが本音だった。
前回、Dify から OpenWebUI に切り替えて、UI や操作感はかなり改善された。
ただ、そこで次にぶつかったのが ユーザー管理問題。
OpenWebUI 単体だと、また個別にユーザーを作って管理する必要がある。
ツールが増えるたびにユーザー管理が増えていく構造は、ひとり情シスにはかなりきつい。
そこで今回、
- Docker 管理を GUI 化するための Portainer
- 認証統合のための Keycloak
- 既存の LINE WORKS を IdP とした SAML 連携
この3点を組み合わせて、
OpenWebUI + SSO + GUI管理構成 を作ることにした。
なお、この構成に至るまでに、Dify を使った検証 → OpenWebUI への切り替え → 現在の構成、という流れを辿っています。
なぜ SSO をやろうと思ったか
正直、SSO は前から知っていた。
ただ「設定が面倒」「証明書」「メタデータ」みたいな単語を見るたびに、後回しにしてきた。
でも、
- ツールが増える
- ユーザー管理も増える
- 削除漏れ、権限ミス、退職者アカウント問題が積み上がる
この流れが見えた時点で、「もう一度ちゃんとやろう」と腹を括った。
ちょうど社内では LINE WORKS を使っていて、
SAML2 に対応している。
Keycloak を中継にして SAML → OpenID Connect 変換すればいけるはず。
理屈は分かっている。
あとは、ひたすら手を動かすだけ。
構成全体イメージ
今回の構成はかなりシンプルにした。
[ LINE WORKS (SAML IdP) ]
↓
[ Keycloak ]
↓
[ OpenWebUI ]
そして、これらのコンテナ管理を Portainer の Web UI で一元管理。
Docker を CLI だけで触るのも悪くないが、
構成が増えてくると、GUI 管理のありがたさが身に染みる。
Portainer での基本方針
docker-compose を Portainer の「Stack」機能で管理 。
流れとしては、
- Portainer にログイン
- 「Stacks」 → 「Add stack」
- docker-compose.yml を貼り付け
- デプロイ
これだけ。
サーバに SSH して compose 叩くより、
履歴管理・再デプロイ・設定の見直し が圧倒的に楽。
OpenWebUI の Stack 定義例
まず OpenWebUI 側。
※ 実際の IP・ドメインは伏せて、サンプルに書き換えている。
version: "3.9"
services:
open-webui:
image: ghcr.io/open-webui/open-webui:0.6.36
container_name: open-webui
volumes:
- data:/app/backend/data
ports:
- "8080:8080"
extra_hosts:
- host.docker.internal:host-gateway
restart: unless-stopped
environment:
# --- OIDC / SSO 設定 ---
OAUTH_CLIENT_ID: "openwebui"
OAUTH_CLIENT_SECRET: "dummy-client-secret"
OPENID_PROVIDER_URL: "https://auth.example.local/realms/openwebui/.well-known/openid-configuration"
OAUTH_PROVIDER_NAME: "SSO Login"
OAUTH_SCOPES: "openid email profile"
OPENID_REDIRECT_URI: "https://openwebui.example.local/oauth/oidc/callback"
# --- ユーザー管理 ---
ENABLE_OAUTH_SIGNUP: "true"
DEFAULT_USER_ROLE: "user"
ENABLE_LOGIN_FORM: "false"
# --- 表示 ---
DEFAULT_LOCALE: "ja-JP"
# --- セキュリティ ---
WEBUI_SECRET_KEY: "dummy-secret-key"
volumes:
data: {}
ポイントは、
ENABLE_OAUTH_SIGNUP=trueOPENID_PROVIDER_URL
ここで Keycloak と連携する。
OpenWebUI は メールアドレス必須 なので、
後述する Keycloak 側で username + .local 付与 という少し強引な加工をしている。
Keycloak の Stack 定義例
次に Keycloak。
version: "3.8"
services:
db:
image: postgres:16-alpine
container_name: keycloak-db
environment:
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: dummy-db-password
POSTGRES_DB: keycloakdb
volumes:
- db_data:/var/lib/postgresql/data
restart: unless-stopped
keycloak:
image: quay.io/keycloak/keycloak:26.4.2
container_name: keycloak
command: >
start
environment:
# --- 管理者アカウント ---
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: dummy-admin-password
# --- DB接続 ---
KC_DB: postgres
KC_DB_URL_HOST: db
KC_DB_URL_PORT: 5432
KC_DB_URL_DATABASE: keycloakdb
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: dummy-db-password
# --- リバースプロキシ前提 ---
KC_HTTP_ENABLED: "true"
KC_PROXY_HEADERS: xforwarded
KC_HOSTNAME: auth.example.local
# --- 機能拡張 ---
KC_FEATURES: "hostname:v2,scripts"
volumes:
db_data:
DB分離、リバースプロキシなどを考慮している 構成。
LINE WORKS (SAML2) 連携のクセ
今回一番ハマったのがここ。
LINE WORKS のユーザー名は、
user01@company
という ドメイン形式ではない 表記。
一方、OpenWebUI 側は メール形式必須。
そのため Keycloak 側で、
${username}.local
という形で 強制的にメール形式へ変換 した。
Keycloak の Mapper 設定で、
- 名前:nameid
- タイプ:Username Template Importer
- テンプレート:${NAMEID}.local
という形にして、無理やり整形。
正直、美しい構成ではない。
でも 現場では「動くこと」が最優先。
この妥協は、かなり現実的な判断だったと思っている。
実際にやってみた感想
正直に言うと、かなり大変だった。
- SAML メタデータのやり取り
- 証明書
- リダイレクト URL
- Attribute Mapping
一つズレると、エラーしか返ってこない。
それでも、
- 一度構成が完成すれば
- ユーザー管理は LINE WORKS 側だけ
- OpenWebUI 側の管理工数はほぼゼロ
ここまで運用が楽になると、
最初の苦労は十分に回収できる と感じた。
今の運用スタンス
今は、
- OpenWebUI → ほぼ放置
- ユーザー管理 → LINE WORKS 側のみ
- Docker 管理 → Portainer の GUI
この形でかなり安定している。
「ひとり情シス」で一番大事なのは、
頑張らなくても回る仕組みを作ること。
技術的に面白い構成より、
自分の手離れが良い構成 を優先した方が、
長期的には絶対に楽になる。
まとめ:この構成を支えているサーバ環境
この構成は、
- OpenWebUI
- Keycloak
- PostgreSQL
- Portainer
と、コンテナ数もそれなりに多くなる。
個人的には、
最初からCPU・メモリに余裕を持たせた Xserver VPS にしておいたのは正解 だったと思っている。
また、今回のような OpenWebUI + SSO 構成は、ネットワークのレスポンスを強く求められる用途ではないため、
Xserver VPS の通常プランでも十分と判断した。
Xserver VPSのビジネスプランと通常プランの違いについては、以下の記事で触れている。

ちなみに、別の記事(SQL Server での業務サーバー構築)では、パフォーマンスと安定性を重視してビジネスプランを選んでいる。
この環境の構成まとめ



