Open WebUI は、ChatGPT のようなチャット画面を自分のサーバーで動かせるツールです。Claude や OpenAI などの API キーを登録すると、その画面から各社のモデルを使えます。API の利用料は使った分だけなので、使う量が少なければ、VPS の料金と API の利用料を合わせても、月額制のサービスより安く済むことがあります。
この記事では、Open WebUI を VPS に Docker で構築し、HTTPS で公開するまでを解説します。手元で動かして分かった、最初の登録の仕様と、外から誰でも開ける状態にしないための設定も紹介します。
必要なメモリ
Open WebUI の公式ドキュメントには、必要なメモリやCPUの最小要件が書かれていません。そこで、手元で測りました。言語モデルは API で外部を使う前提のため、Open WebUI と Caddy だけの値です。
- 標準のイメージは、文書検索(RAG)や音声のための機械学習の仕組みを含んでいて、何もしていなくても約0.9GiB を使いました。2GB のプランを選んでください。
- slim イメージは、こうした機能を外したものです。手元では約0.3GiB で、1GB のプランでも収まります。ただし、文書の取り込みや音声などの機能には、別のサービスが必要になります。チャットだけに使うなら、slim イメージで十分です。使うときは、
image:をghcr.io/open-webui/open-webui:v0.12.3-slimにします。
構成
インターネット ──> Caddy(80/443、HTTPS) ──> Open WebUI(外には公開しない)──> Claude・OpenAI などの API
公式の手順は -p 3000:8080 で Open WebUI のポートを直接公開しますが、基本手順の記事で書いたとおり、Docker で公開したポートは ufw の設定を通りません。この記事では、ほかの記事と同じく、Caddy だけを外に出します。
手順1:VPS に Docker を入れ、DNS を設定する
Docker Compose で HTTPS 公開する基本手順のとおり、Docker を公式の手順で入れます。使うドメイン(例:chat.example.com)の A レコードを、VPS の IP アドレスに向けておきます。
手順2:ファイルを作る
作業用のディレクトリ(例:~/open-webui)に、3つのファイルを作ります。
compose.yaml:
services:
caddy:
image: caddy:2.11.7
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- WEBUI_DOMAIN=${WEBUI_DOMAIN}
- ALLOWED_IPS=${ALLOWED_IPS}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
open-webui:
image: ghcr.io/open-webui/open-webui:v0.12.3
restart: unless-stopped
expose:
- "8080"
environment:
- WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
- WEBUI_URL=https://${WEBUI_DOMAIN}
- WEBUI_SESSION_COOKIE_SECURE=true
- CORS_ALLOW_ORIGIN=https://${WEBUI_DOMAIN}
volumes:
- open-webui:/app/backend/data
volumes:
caddy_data:
caddy_config:
open-webui:
Caddyfile:
{$WEBUI_DOMAIN} {
# 許可した IP アドレス以外からのアクセスを断る(ALLOWED_IPS は空白区切りで複数書ける)
@blocked not remote_ip {$ALLOWED_IPS}
respond @blocked "Forbidden" 403
reverse_proxy open-webui:8080
}
.env:
WEBUI_DOMAIN=chat.example.com
# 自宅や職場の IP アドレス。分からなければ「IP アドレス 確認」で検索して調べる
ALLOWED_IPS=203.0.113.10/32
# openssl rand -hex 32 で作った値に置き換える
WEBUI_SECRET_KEY=ここに値を入れる
ポイントは次のとおりです。
- イメージは版の番号で固定します。 公式の例にある
:mainは、新しい変更が入るたびに中身が変わるタグです。公式のセキュリティの手引きも、本番では版の番号を指定し、自動では更新しないよう勧めています。 WEBUI_SECRET_KEYは必ず固定値にします。 ログイン用のトークンの署名と、一部の保存データ(MCP の認証情報やアプリの API キーなど)の暗号化に使われます。設定しないとコンテナの中で自動で作られ、コンテナを作り直したときに変わることがあります。そうなると、全員がログアウトされ、保存した情報が読めなくなる場合があると、公式ドキュメントは説明しています。WEBUI_URL、WEBUI_SESSION_COOKIE_SECURE、CORS_ALLOW_ORIGINは、自分のドメインと HTTPS で使う前提の設定です。CORS_ALLOW_ORIGINは既定ではすべての送信元を許すため、公式のセキュリティの手引きに従って自分のドメインに絞っています。WEBUI_URLは初回の起動後は画面の設定が優先されるため、あとからドメインを変えるときは管理者パネルで変えます。ALLOWED_IPSで、開ける人を自分に限ります。 理由は後の「外から誰でも開ける状態にしない」で説明します。
手順3:起動して、すぐに管理者を登録する
docker compose up -d
初回の起動では、標準のイメージは文書検索用のモデルを自動でダウンロードします。手元では起動が終わるまで約2分かかりました。その間、docker compose ps では unhealthy と表示されることがありますが、待てば正常になります。
起動したら、すぐに https://chat.example.com を開いて、管理者のアカウントを作ります。最初に登録した人が管理者になります。 手元で確かめたところ、1人目の登録で管理者になり、そのあとの2人目の登録は拒否されました。公式ドキュメントによると、最初の登録のあと、新規の登録は自動で閉じます。
手順4:Claude や OpenAI の API をつなぐ
API キーは、画面から登録します。管理者でログインし、管理者パネル → 設定 → 接続 の「OpenAI API接続の管理」で接続を追加し、接続先の URL と API キーを入れます。保存しただけでは接続を確かめないため、接続の確認(Verify Connection)も行います。
| 使いたいモデル | 接続先の URL | API キーの発行元 |
|---|---|---|
| OpenAI(GPT) | https://api.openai.com/v1 |
OpenAI のダッシュボード |
| Claude | https://api.anthropic.com/v1 |
Anthropic Console |
Claude は、Anthropic が用意している OpenAI 互換の API で接続します(Open WebUI 公式の手順)。ただし、Anthropic 自身がこの互換の API を「評価やテスト向け」としていることを、Open WebUI の公式ドキュメントが注意として紹介しています。PDF の処理やプロンプトのキャッシュなどを使うには、互換の API ではなく Anthropic のネイティブの API が勧められています。
環境変数で接続先を設定するときの注意
接続先は OPENAI_API_BASE_URL などの環境変数でも指定できます。ただし、Open WebUI の多くの設定は、初回の起動時だけ環境変数から読み込まれ、そのあとはデータベースに保存された値が使われます。あとから環境変数を書き換えても反映されないことがあるため、起動後の変更は画面から行うのが確実です。
外から誰でも開ける状態にしない
Open WebUI の公式のセキュリティの手引きは、認証などの仕組みを前に置かずに、インターネットに直接公開しないよう明記しています。
GitHub で公表されたセキュリティアドバイザリを数えると、2026年1月1日から10月24日までに159件ありました(Critical 1件、High 66件)。多くは「ログインできる人」が前提の問題ですが、管理者のログイン画面が誰からも見える状態は避けたいところです。
この記事の構成では、Caddy で許可した IP アドレス以外からのアクセスを断るようにしました。手元で、許可していない IP アドレスからは 403(拒否)が返り、許可した IP アドレスからは開けることを確かめています。
- 外出先など、IP アドレスが変わる場所から使いたい場合は、VPN(Tailscale など)を使い、VPN の IP アドレスだけを許可する方法があります。
- 家族やチームで使う場合は、管理者パネルからユーザーを追加するか、IP アドレスの制限をかけたまま、必要な間だけ新規登録を有効にします。公式の既定では、新しく登録した人は「承認待ち」になり、管理者が承認するまで使えません。公式のセキュリティの手引きは、信頼できないネットワークから届く状態で登録を開けたままにしないよう求めています。
バックアップ
チャットの履歴、ユーザー、設定は、すべて open-webui ボリュームに入っています。公式の例とほぼ同じ方法で、ボリュームを固めます(自動でダウンロードされるファイルは除きます)。
docker compose stop open-webui
docker run --rm -v open-webui_open-webui:/data -v "$PWD":/backup alpine:3.22 \
tar czf /backup/openwebui-$(date +%Y%m%d).tar.gz --exclude=./cache -C /data .
docker compose start open-webui
ボリューム名は「ディレクトリ名_open-webui」になります。docker volume ls で確認してください。
--exclude=./cache は、自動でダウンロードされる文書検索用のモデルなどを除くための指定です。手元では、この cache だけで約1GB あり、除くとバックアップは約30KB になりました(チャットが少ない状態)。文書検索用のモデルは、復元後の起動時に再びダウンロードされるはずです。
復元は、次のように行います。公式ドキュメントの復元コマンドは、ファイルの中の形が違うため、このバックアップにはそのまま使えません。
docker compose stop open-webui
docker run --rm -v open-webui_open-webui:/data -v "$PWD":/backup alpine:3.22 \
sh -c "rm -rf /data/* && tar xzf /backup/openwebui-20261024.tar.gz -C /data"
docker compose start open-webui
ファイル名の日付は、自分のバックアップに合わせてください。手元では、slim イメージの環境でこの手順を実行し、既存の管理者でログインできることを確かめました。公式ドキュメントは、データベースの変換は一方通行で、コンテナの版を戻しても元に戻らないと説明しています。更新の前には必ずバックアップを取ってください。
更新
compose.yaml の image: の版を書き換えて、起動し直します。
docker compose pull open-webui
docker compose up -d
新しい版は GitHub のリリース一覧で確認できます。2026年10月は数日おきに新しい版が出ていました。
VPS の選び方
標準のイメージなら 2GB、slim イメージなら 1GB のプランで足ります。言語モデルは外部の API で動かすため、CPU の性能はあまり要りません。
| サービスとプラン | 1ヶ月契約 | 最長契約の月額 | ファイアウォール | 新規申込 |
|---|---|---|---|---|
| KAGOYA CLOUD VPS2GB、2コア、NVMe SSD 200GB | 770円 | 715円12ヶ月(年額) | 初期状態は全許可セキュリティグループ | 停止中 |
| WebARENA Indigo2GB、2コア、SSD 40GB | 814円 | 814円なし(時間課金のみ) | 未確認セキュリティグループ | 停止中 |
| シンVPS大容量メモリ 2GB、2コア、NVMe SSD 50GB | 1,040円 | 950円36ヶ月 | 未確認パケットフィルター | 受付中 |
| ConoHa VPS2GB、3コア、SSD 100GB | 1,259円初回 1,007円 | 903円36ヶ月初回 677円 | 初期状態で拒否セキュリティグループ | 受付中 |
| ABLENET VPSL1、2コア、SSD 40GB | 1,476円初回 1,234円 | 1,130円12ヶ月(年払い)初回 968円 | 記載なし | 受付中 |
| さくらのVPS2G、3コア、SSD 100GB | 1,738円 | 1,594円12ヶ月 | 一部だけ制限パケットフィルター | 一部のみ受付 |
| XServer VPS2GB、3コア、NVMe SSD 50GB受付停止の告知(7月14日)のあと、再開の告知が見当たらない | 1,980円 | 1,265円36ヶ月 | 初期状態で拒否パケットフィルター | 受付中 |
に各社の公式ページで確認した価格です。1ヶ月契約は更新時の価格で、時間課金・日額課金しかない会社は月額の上限を載せています(ConoHa VPS は一括前払いの1ヶ月の価格で、時間課金はこれより上限が高くなります)。最長契約の月額は、最も長い契約期間の料金を1ヶ月あたりに換算した額です。ファイアウォールは、VPS の管理画面で設定できるものの初期状態です。申込の受付状況は変わりやすいため、契約の前に公式ページで確かめてください。
- ConoHa VPS: 初回の価格は 2026年10月29日までのキャンペーン価格で、申し込み時だけ適用されます
- ABLENET VPS: 初回の価格は「契約時特別価格」で、最初の支払いだけに適用されます(期限の記載なし)
Open WebUI の上で Ollama などのモデルを VPS 内で動かす場合は、話が変わります。モデルの大きさに応じて、さらに多くのメモリと CPU が必要です。