導入の背景と直面していた課題
約半年前、開発メンバーからマーケティングまで計35名規模の弊社のチームでは、毎月個別に契約されたChatGPT Plusのアカウント代だけで、会社のクレジットカードから700米ドル近くが引き落とされていました。コストの肥大化も大きな問題でしたが、それ以上に深刻だったのは、メンバーが無自覚にデータベースのスキーマやプロジェクトのソースコードをパブリックなクラウドAIサービスに貼り付けてしまうというセキュリティ上のリスクでした。
そこで最も現実的な打開策として浮上したのが、社内のプライベートサーバー上に専用のAI Gatewayを立ち上げることでした。DockerとOpen WebUIを組み合わせることで、以下の3つの課題を根本から解決することができました。
- データの完全管理:チャット履歴、アップロードファイル、Embeddingsデータはすべて社内データベース内に完結して保存されます。社外の監視や統制なしにプロンプトが外部へ流出することはありません。
- 柔軟なモデル切り替え:機密性の高い社内文書を扱う場合は、ローカルのOllama経由で動くLlama 3.1 8BやQwen 2.5を利用。高度なコーディングや長文レポートの分析が必要な場合は、共有APIプール経由でGPT-4oやClaude 3.5 Sonnetへと、ワンクリックで瞬時に切り替えが可能です。
- コスト削減とアクセス権限の集中管理:各メンバーにAPIキーを直接配布する代わりに、部門ごとに利用枠(クォータ)を割り振ったり、Admin/Userのロールを付与して高額なモデルの利用を制限したりといった運用が管理画面から容易に行えます。
Docker Composeによるインストール手順
かつてPythonのvenv環境に直接インストールしようとして、CUDAやC++ライブラリのバージョン競合に散々悩まされた苦い経験から、結論としてDocker Composeでの導入を強く推奨します。ホスト環境をクリーンに保てるだけでなく、アップグレードやサーバー移行もわずか5分で完了します。
まずは、Ubuntu/Debianサーバー上でプロジェクト用のディレクトリを作成します。
mkdir -p /opt/ai-gateway/data && cd /opt/ai-gateway
本番運用に適した標準設定でdocker-compose.ymlを作成します。
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
restart: always
ports:
- "127.0.0.1:3000:8080"
environment:
- WEBUI_SECRET_KEY=koko_ni_32_moji_ijou_no_randamu_mojiretsu_wo_settei
- DATA_DIR=/app/backend/data
- ENABLE_SIGNUP=true
- DEFAULT_MODELS=llama3.1:8b
- OPENAI_API_BASE_URLS=http://host.docker.internal:11434/v1;https://api.openai.com/v1
- OPENAI_API_KEYS=ollama;sk-proj-your-openai-api-key-here
volumes:
- ./data:/app/backend/data
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
コンテナをバックグラウンドで起動します。
docker compose up -d
イメージのプルとデータベースのマイグレーションが完了するまで約1分待ちます。その後、docker compose logs -fコマンドで起動ログを確認できます。
インストール後の詳細設定
Web画面で最初にサインアップしたユーザーに、自動的にRoot Admin(最高管理者)権限が付与されます。この管理者アカウントの登録が完了したら、直ちに以下の重要項目を設定してください。
1. マルチモデル接続(ローカルGPUとクラウドAPIの統合)
Admin Panel > Settings > Connections に移動し、各モデルへの接続設定を確認・追加します。
- ローカルのOllama:デフォルト設定では、ホストマシン上で直接稼働しているOllamaを指すために
http://host.docker.internal:11434を使用します。社内LAN上に専用のGPUサーバー(例:RTX 4090や3090を搭載したマシン)を構築している場合は、http://192.168.1.100:11434のようなプライベートIPに変更してください。 - OpenAIやLiteLLM:エンドポイントURLとAPIキーをリストに直接追加します。LiteLLMやvLLMといったプロキシゲートウェイを導入している場合でも、Open WebUIは標準的な
/v1エンドポイント仕様と完全な互換性があります。
実際の運用上、すべてのモデル接続を単一のゲートウェイに集約することで、エンジニアやテスターが各アプリケーションにAPIキーを手作業でコピー&ペーストする手間と漏洩リスクを完全に排除できます。
2. 新規ユーザー登録の制限とモデル利用権限の割り当て
不特定多数のユーザーが自由にサインアップできないよう、登録制限をかけます。
- Settings > GeneralタブにあるEnable New Sign Upsを直ちに無効化します(または、docker-composeファイルの環境変数を
ENABLE_SIGNUP=falseに変更して再起動します)。 - Usersタブから、対象メンバーのアカウントを手動で個別作成します。
- デフォルトモデルを制限:コストを抑えるため、一般の開発メンバーにはOllama上のローカルモデルのみを割り当て、GPT-4oやClaude 3.5 Sonnetなどの商用APIはTech LeadやProduct Managerなど必要な権限グループにのみ開放します。
3. Nginxリバースプロキシによるポート保護とSSL暗号化
ポート3000をインターネット上に直接公開することは絶対に避けてください。NginxをリバースプロキシおよびSSL終端として配置し、社内ドメインを割り当てます。
server {
listen 80;
server_name ai.company.internal;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name ai.company.internal;
ssl_certificate /etc/ssl/certs/company_ai.crt;
ssl_certificate_key /etc/ssl/certs/company_ai.key;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# SSEとトークンストリーミングの遅延・切断を防ぐために必須
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 600s;
proxy_buffering off;
proxy_cache off;
}
}
特にproxy_buffering off;の設定は極めて重要です。この設定がないと、Nginxがレスポンスを一定量バッファリングしてからクライアントに返そうとするため、リアルタイムなトークンごとのストリーミング出力が正常に描画されなくなります。
稼働テストと実運用におけるポイント
社内全体にURLをアナウンスする前に、以下の3つの検証シナリオをテストしておく必要があります。
1. リソース消費のベンチマーク
以下のコマンドを用いてコンテナのリソース状態をモニタリングします。
# リアルタイムログを確認
docker logs -f --tail=100 open-webui
# RAMとCPUの使用状況を確認
docker stats open-webui
アイドル状態では、Open WebUIのメモリ消費量は350MB〜600MB程度です。しかし、社内ドキュメントQA(RAG)機能で約10名が同時にPDFファイルをアップロードして処理を行うと、使用メモリが1.8GB〜2.2GBまで急増することがあります。このサービス専用として、最低でも4GB以上のRAMを搭載したサーバーを用意することをお勧めします。
2. ストリーミング応答とファイルアップロードの検証
一般ユーザーアカウントでログインし、実際の使い勝手を検証します。
- Llama 3.1でのテストチャット:送信ボタンを押してから最初のトークンが表示されるまでのレイテンシを測定します。コンテナとOllama間のブリッジネットワーク接続が正常であることを確認してください。
- GPT-4oへの切り替え:ストリーミング応答が途切れずスムーズに返ってくるか、60秒以上経過してもタイムアウトエラーが発生しないかを確認します。
- 約15ページの財務レポートPDFをドラッグ&ドロップ:ファイル内の特定の事実や数値を質問し、バックエンドがドキュメントを正確にチャンク分割(Chunking)し、埋め込み(Embedding)検索が機能しているか検証します。
3. 定期的なデータバックアップ
すべてのチャット履歴、ユーザー情報、アップロードされたドキュメントは/opt/ai-gateway/dataディレクトリに完全に保存されます。毎晩深夜2時にこのディレクトリをNASやS3バケットへrsyncで同期するcronジョブを設定しておくだけで、長期間にわたって安心して運用を継続できます。

