概要
Open WebUIとは、無料で利用可能なAIエージェントインターフェースである。
ChatGPT風のAIエージェント画面を、セルフホストできるようにしたもの、と考えるとわかりやすい。
自身でホストしたAIや契約中のAIサービスと連携して、AIとのチャットや音声チャット、RAG、ワークスペース管理などを行うことができる。ユーザ・グループ管理機能を備えているため、個人利用はもちろん、組織利用も可能である。
さくらインターネット株式会社が提供するさくらのAI Engineは、OpenAI互換APIを提供しており、Open WebUIもこれに対応しているため、さくらのAI Engineをバックエンドにしつつ、ChatGPT風のリッチなエージェント画面をOpen WebUIで実現することが可能である。
構築
今回は、nginxをリバースプロキシとして、サーバ上でコンテナ稼働するOpen WebUIを利用する方法を選択した。
サーバ構築
Terraformでさくらのクラウドにサーバを構築する。スタートアップスクリプトを用いて、nginx、certbot、dockerおよびその依存パッケージを構築段階でインストールしている(手動でやっても問題ない。基本的な内容なのでここでは詳細を割愛する)。

サーバのIPアドレスが発行される。
ドメインの割り当て
発行されたIPアドレスに、Open WebUIをホストするドメインを割り当てる。私の場合はさくらのドメインのドメインコントロールパネルでAレコードを追加した。

サーバ初期設定
以下コマンドを叩いて、サーバにログインする。
ssh -i .\.ssh\id_rsa.pem ubuntu@IPアドレス
SSH設定やファイアウォール設定はよしなに行う。
その上で、先ほど割り当てたドメインでLet's Encryptの証明書取得を行う。これにより、HTTPS対応を完了させる。
sudo certbot --nginx

取り急ぎ、割り当てたドメインでnginxのページが表示されるようになった。

続けて、コンテナを立ち上げ、URLからOpen WebUIに入れるようにする。
Dockerコンテナ構築
Open WebUIのシークレットキー生成
Open WebUIの動作に必要なシークレットキーを乱数生成する。
openssl rand -hex 32
さくらのAI Engineトークン取得
さくらのAI Engineを呼ぶ際に必要なアカウントトークンを発行する。

音声機能を使いたい場合は、あらかじめ使いたい音声モデルの利用規約に同意しておこう。
Docker composeファイル群作成
フォルダを作成し、移動する。
sudo mkdir -p /opt/docker/openwebui
cd /opt/docker/openwebui/
まず、docker-compose.ymlを作成する。環境変数でさくらのAI Engineを使うようにしているほか、自動更新もできるようにした。
sudo nano docker-compose.yml
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
ports:
- "127.0.0.1:8080:8080"
volumes:
- open-webui:/app/backend/data
extra_hosts:
- host.docker.internal:host-gateway
environment:
- PORT=8080
- WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
- WEBUI_URL=設定したドメイン
- ENABLE_MFA=True
- ENABLE_OLLAMA_API=False
- OPENAI_API_BASE_URL=https://api.ai.sakura.ad.jp/v1
- OPENAI_API_KEY=${OPENAI_API_KEY}
- RAG_OPENAI_API_BASE_URL=https://api.ai.sakura.ad.jp/v1
- RAG_OPENAI_API_KEY=${OPENAI_API_KEY}
- RAG_EMBEDDING_ENGINE=openai
- RAG_EMBEDDING_MODEL=multilingual-e5-large
- ENABLE_WEB_SEARCH=True
- WEB_SEARCH_ENGINE=duckduckgo
- AUDIO_STT_OPENAI_API_BASE_URL=https://api.ai.sakura.ad.jp/v1
- AUDIO_STT_OPENAI_API_KEY=${OPENAI_API_KEY}
- AUDIO_STT_ENGINE=openai
- AUDIO_STT_MODEL=whisper-large-v3-turbo
- AUDIO_TTS_OPENAI_API_BASE_URL=https://api.ai.sakura.ad.jp/v1
- AUDIO_TTS_OPENAI_API_KEY=${OPENAI_API_KEY}
- AUDIO_TTS_ENGINE=openai
- AUDIO_TTS_MODEL=利用規約確認済の音声モデル
- AUDIO_TTS_VOICE=normal
restart: unless-stopped
watchtower:
image: nickfedor/watchtower
container_name: watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
command: --interval 21600 open-webui
restart: unless-stopped
volumes:
open-webui:
続けて、設定ファイルも作成する。
sudo nano .env
# セキュリティキー
WEBUI_SECRET_KEY=コマンドで生成した乱数
# APIキー (さくらのAI Engine)
OPENAI_API_KEY=さくらのAI Engineのアカウントトークン
.envファイルは機密情報を含むので、権限管理は厳重に。筆者の場合は600で設定した。
ここまできたら、コンテナを起動する。
sudo docker compose up -d
nginxの設定
続けて、nginxのルーティングを設定し、Open WebUIをURLで開けるようにする。
nginxの設定ファイルを作成する。様々な設定項目があるが、Open WebUI公式ドキュメントに準拠して設定すると、おおむねこのような形になる。
sudo nano /etc/nginx/conf.d/openwebui.conf
map $http_upgrade $openwebui_connection {
default upgrade;
'' '';
}
upstream openwebui {
server 127.0.0.1:8080;
keepalive 128;
keepalive_timeout 1800s;
keepalive_requests 10000;
}
server {
listen 80;
listen [::]:80;
server_name 設定したドメイン;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name 設定したドメイン;
ssl_certificate /etc/letsencrypt/live/設定したドメイン/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/設定したドメイン/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
gzip on;
gzip_types text/plain text/css application/javascript image/svg+xml;
# API endpoints - streaming optimized
location /api/ {
proxy_pass http://openwebui;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
# CRITICAL: Disable all buffering for streaming
gzip off;
proxy_buffering off;
proxy_request_buffering off;
proxy_cache off;
tcp_nodelay on;
add_header X-Accel-Buffering "no" always;
add_header Cache-Control "no-store" always;
# Extended timeouts for LLM completions
proxy_connect_timeout 1800;
proxy_send_timeout 1800;
proxy_read_timeout 1800;
}
# WebSocket endpoints
location ~ ^/(ws/|socket\.io/) {
proxy_pass http://openwebui;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
gzip off;
proxy_buffering off;
proxy_cache off;
# 24-hour timeout for persistent connections
proxy_connect_timeout 86400;
proxy_send_timeout 86400;
proxy_read_timeout 86400;
}
# Static assets - CAN buffer and cache
location /static/ {
proxy_pass http://openwebui;
proxy_buffering on;
proxy_cache_valid 200 7d;
add_header Cache-Control "public, max-age=604800, immutable";
}
# Default location
location / {
proxy_pass http://openwebui;
proxy_http_version 1.1;
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;
}
}
作成が終わったら、nginxをリロードする。
# 既定のルーティングを解除
sudo unlink /etc/nginx/sites-enabled/default
# 設定をロード
sudo systemctl reload nginx
Open WebUIを使ってみる
ここまできたら、ドメインにアクセスすればOpen WebUIが表示される。

「はじめる」を押下すると、ユーザ作成画面が表示されるので、登録を済ませよう。登録が完了すると、

無事チャット画面が表示された。
環境変数でさくらのAI Engine利用に必要な設定は済ませてあるので、チャットを動かしてみるとすぐ応答が返ってくる。

音声チャットを利用することも可能だ。

Web検索機能も使えるように環境変数を設定してあるので、ウェブ検索にチェックを入れて使えば最新の情報を元に回答することもできる。

問題なく使うことができそうだ。
まとめ
今回はさくらのクラウド上のサーバでOpen WebUIを起動し、Open WebUI経由でさくらのAI Engineを利用できるようにしてみた。
さくらのAI Engine自体にもPlaygroundというGUIエージェント機能はあるが、Open WebUIを使えば音声チャットやRAGなどの機能を気軽に使うことができるほか、PWAを用いることでスマホアプリとしても利用できるのでおすすめだ。
筆者も、Open WebUIを用いて、さくらのAI Engineを個人AIエージェントとして利用している。
みなさんもぜひ試してみて欲しい。