毎月のように最強のLLMが登場する昨今、登場するたびに提供会社のWebUIに慣れるのは大変です。 そこで過去に紹介したLiteLLMとOpenWebUIを組み合わせて様々なLLMサービスを統一したWebコンソール上で利用できるようなサービスを自分用にデプロイしたいと思います。
Open WebUIについて

GitHub - open-webui/open-webui: User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
ChatGPTやGeminiなど一般的なLLMのWebサービスUI的な物のオープンソース版です。一般的なチャット、画像等のファイルアップローダー、Web検索(スクレイピングツールの繋ぎ込みが必要)など欲しい機能がひととおり揃っています。(昔はOllma WebUIという名前でした)
提供されてるのはフロントのみなのでLLM部分はOllamaやLiteLLM、各種サービスへ繋ぎ込み等が必要です。
LiteLLMについて
様々なLLMサービスをOpenAIと同じインターフェースで使えるようにしてくれるproxyソフトです。

LiteLLMを使ってBedrockのClaudeをOpenAIのAPIと同じように使う
過去にBedrockのClaudeをOpenAIと同じインターフェースで利用する方法を記事にしました。
とりあえずLiteLLM経由で利用すれば実装はOpenAI用の物のみですむのでLLMを利用したプログラムを書くのであれば利用して損の無いソフトウェアです。
環境
今回はUbuntu Server 22.04上でDockerを起動して各種ソフトを運用します。LLM自体の処理はクラウド側で行うためラズパイなど非力なサーバーでも利用可能かと思います。
OpenWebUIやLiteLLM以外の複数コンテナが走っている既存環境ですのでRAMは16GB積んでいますが。
LiteLLMの構成
前回の記事から時間が経ちWebUI等が増えているため再度構築を行います。

GitHub - BerriAI/litellm: Python SDK, Proxy Server (LLM Gateway) to call 100+ LLM APIs in OpenAI format - [Bedrock, Azure, OpenAI, VertexAI, Cohere, Anthropic, Sagemaker, HuggingFace, Replicate, Groq]
リポジトリから.env.example、docker-compose.yaml、prometheus.ymlを取ってきます。素直にリポジトリをcloneしてもOKです。
docker-compose.yaml
まずdocker-compose.yamlですがconfig.yaml
の指定とマウント、そしてrestart: always
を付与して再起動時も自動で起動するように変更しました。それ以外はリポジトリ構成のままです。
services:
litellm:
build:
context: .
args:
target: runtime
image: ghcr.io/berriai/litellm:main-stable
volumes:
- ./config.yaml:/app/config.yaml
command: ["--config", "/app/config.yaml"]
ports:
- "4000:4000" # Map the container port to the host, change the host port if necessary
environment:
DATABASE_URL: "postgresql://llmproxy:dbpassword9090@db:5432/litellm"
STORE_MODEL_IN_DB: "True" # allows adding models to proxy via UI
env_file:
- .env # Load local .env file
restart: always
db:
image: postgres
restart: always
environment:
POSTGRES_DB: litellm
POSTGRES_USER: llmproxy
POSTGRES_PASSWORD: dbpassword9090
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -d litellm -U llmproxy"]
interval: 1s
timeout: 5s
retries: 10
prometheus:
image: prom/prometheus
volumes:
- prometheus_data:/prometheus
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
restart: always
volumes:
prometheus_data:
driver: local
.env
続いて .env はexampleからの改変で下記の様にしました。
私はBedrock、OpenAI、Gemini、DeepSeekを利用しているので各サービスを利用するのに必要なTokenを記載しています。ここは各個人で利用したいサービスのTokenを記載してください。
利用可能なサービスは下記のドキュメントに記載されています。

Providers | liteLLM
SLACK_WEBHOOK_URL
は各種サービスのAPIエラーなどを通知するためのSlackのWebhook URLを記載します。私はDiscordを利用しているのでDiscordのWebhook URLに末尾/slackを追加して記載しています。
このようにRate Limitや課金不足などのエラーがPostされるようになります。
UI_USERNAME
、UI_PASSWORD
はWebUIにログインするためのユーザー名とパスワードです。WebUIでは各サービスの概算利用料等が確認できます。
LITELLM_MASTER_KEY
はLiteLLMのAPIを利用するときのTokenになります。前述のWebUIで都度Tokenの発行は可能ですが2025年3月1日現在、すこし挙動がおかしいところもあるので今回はこのMasterTokenを使い回します。
AWS_ACCESS_KEY_ID =
AWS_SECRET_ACCESS_KEY =
AWS_REGION_NAME = us-west-2
OPENAI_API_KEY =
GEMINI_API_KEY =
DEEPSEEK_API_KEY =
SLACK_WEBHOOK_URL =
UI_USERNAME=
UI_PASSWORD=
LITELLM_MASTER_KEY =
DATABASE_URL = postgresql://llmproxy:dbpassword9090@db:5432/litellm
STORE_MODEL_IN_DB = True
config.yaml
config.yamlにはどのAPIをどのTokenで利用するか記述します。私はBedrock、OpenAI、Gemini、DeepSeekを利用しているので下記の様に記載しています。2025年3月1日時点での有名処は網羅してると思います。
BedrockでClaude 3.7 Sonnetを利用する際に前にus.
を付けてbedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0
にしないと通らなかったので注意です。
OpenAIのo3系が入っていないのは私のAPIのTierが不足していて使えないためです。
model_list:
- model_name: gemini-2.0-flash
litellm_params:
model: gemini/gemini-2.0-flash
api_key: os.environ/GEMINI_API_KEY
- model_name: gemini-2.0-flash-thinking-exp-01-21
litellm_params:
model: gemini/gemini-2.0-flash-thinking-exp-01-21
api_key: os.environ/GEMINI_API_KEY
- model_name: gemini-2.0-pro-exp-02-05
litellm_params:
model: gemini/gemini-2.0-pro-exp-02-05
api_key: os.environ/GEMINI_API_KEY
- model_name: bedrock-claude-3.7-sonnet
litellm_params:
model: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0
aws_access_key_id: os.environ/AWS_ACCESS_KEY_ID
aws_secret_access_key: os.environ/AWS_SECRET_ACCESS_KEY
aws_region_name: os.environ/AWS_REGION_NAME
- model_name: gpt-4o-mini
litellm_params:
model: openai/gpt-4o-mini
api_key: os.environ/OPENAI_API_KEY
- model_name: gpt-4o
litellm_params:
model: openai/gpt-4o
api_key: os.environ/OPENAI_API_KEY
- model_name: o1
litellm_params:
model: openai/o1
api_key: os.environ/OPENAI_API_KEY
- model_name: o1-mini
litellm_params:
model: openai/o1-mini
api_key: os.environ/OPENAI_API_KEY
- model_name: deepseek-chat
litellm_params:
model: deepseek/deepseek-chat
api_key: os.environ/DEEPSEEK_API_KEY
- model_name: deepseek-coder
litellm_params:
model: deepseek/deepseek-coder
api_key: os.environ/DEEPSEEK_API_KEY
- model_name: deepseek-reasoner
litellm_params:
model: deepseek/deepseek-reasoner
api_key: os.environ/DEEPSEEK_API_KEY
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
alerting: ["slack"]
prometheus.yml
リポジトリから変更するところはありません。
初期設定
これで準備が整いましたのでdocker compose up -d
でコンテナを起動します。
コンテナ起動後はCurlでAPIが利用できるか確認します。
curl --location 'http://[サーバーIPアドレス]:4000/chat/completions' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer [envで設定したLITELLM_MASTER_KEY]" \
-d ' {
"model": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "what llm are you"
}
]
}'
'
これが通ればOpenAIと同じインターフェースで各種LLMが利用できるようになっていますので、後は使いたいサービスに設定するだけで利用可能です。
Webui
http://[サーバーIP]:4000
にアクセスするとSwaggerが表示されます。すべての機能はREST API制御可能です。まぁ私はchat/completions
しか利用したことありませんが……
http://[サーバーIP]:4000/ui
にアクセスするとWebUIが利用可能です。.envで設定したIDとPASSでログインできます。Usageを開くと各モデルをどの程度利用したか、日次の利用料金などが確認可能です。利用料金は各サービスのToken定価から算出されるのでズレが発生する点に留意が必要です。特にDeepSeekなどキャッシュヒットした場合の返金等がある場合は大きくズレます。
Virtual Keysの画面でLiteLLMを利用するためのTokenを追加発行可能です。この機能でLiteLLMにアクセスするサービス毎にTokenを分けられてセキュアかつUsageの画面で利用料金がToken毎に表示されてわかりやすいという利点があります。
あるのですが、このページを開くと下記のようなエラーが表示されてToken一覧が表示されません。
{"error":{"message":"Internal Server Error, 'NoneType' object is not iterable","type":"internal_server_error","param":"None","code":"500"}}
発行されたTokenは有効ですしUsageの画面でのToken毎の利用料金が見られるので問題ないのですが、Token一覧が表示できないとTokenの削除ができません。
GitHubでIssueは立っているのでそのうち治ると思います。

[Bug]: NoneType object is not iterable · Issue #8240 · BerriAI/litellm
OpenWebUIの構成

⏱️ Quick Start | Open WebUI
こちらも公式ドキュメントを参考に組んでいきます。もちろんdocker composeで構築します。
docker-compose.yaml
大きくドキュメントから変更はしていません。8080番ポートは大人気で被るのでホスト側の割当ポートを変更しています。またOpenAIとしてLiteLLMの繋ぎ込みをしています。
services:
open-webui:
image: ghcr.io/open-webui/open-webui
restart: unless-stopped
container_name: open-webui
volumes:
- open-webui:/app/backend/data
ports:
- 8182:8080
environment:
- WEBUI_SECRET_KEY=
- ENABLE_OLLAMA_API=false
- OPENAI_API_BASE_URL=http://[LiteLLMを入れたサーバーIP]:4000
- OPENAI_API_KEY=[LiteLLMで設定したLITELLM_MASTER_KEY]
volumes:
open-webui: {}
デフォルトではWebUIを表示する際にログインが必要なのですがenvironmentにWEBUI_AUTH=false
を設定することでログイン無しにすることもできます。サーバーではなくローカルDockerなどで運用する場合は他人がアクセスしてくる可能性も低いと思うのでオススメの設定です。
起動
docker compose up -d
でコンテナを起動します。
初回起動ではアカウント作成が必要なので作ります。WEBUI_AUTH=false
になってれば不要です。
ログイン後に左上のモデル一覧からLiteLLMで繋ぎ込んだLLMモデル一覧が出てきたら完成です。
UIとしては世間一般の見慣れたLLMサービスのUIになってるので学習コストは低いと思います。
OpenWebUIおすすめ設定
私がやっているOpenWebUIのおすすめ設定をいくつか紹介します。
起動時のWhat’s Newを非表示化
設定 > インターフェースの「Show “What’s New” modal on login」をオフにするとログイン時に出てくるWhat’s Newが出なくなります。
アップデートがありますのトーストを非表示
What’s New設定の1個上のToast notifications for new updatesをオフにすることで消えます。個人的にはアップデートが来たら即時アップデートしたい人間なので消してませんが消すと便利な人も居るでしょう。(とくにスマホで使う場合とか)
新規登録の無効化
デフォルトでオフだった記憶ですが、管理者設定画面から新規登録を無効化できます。セキュリティ上オフの方が良いでしょう。
WebUIのアドレス登録
管理者設定画面でWebUIのアドレスを登録しておくとチャットの共有機能等でアクセスできるURLが埋め込まれます。
社内ツールとして複数人が見られる環境の場合は設定しておくと便利です。
タイトル生成などに利用するLLMモデルの設定
OpenWebUIにもチャットのタイトルを生成する機能があります。これがデフォルト設定だとチャットに利用しているLLMモデルがタイトル生成などに使われます。
SonnetやChatGPT-4.5などトークン単価の高いモデルでタイトル生成を行うのは無駄なのでgemini-flashなど単価の安いモデルを指定することをオススメします。
また個人的にAutocomplete Generationはオフにしています。
Cloudflare Tunnel経由での外部アクセス
デプロイしたOpenWebUIを自宅外でもアクセスできるようにすると非常に便利です。OpenWebUIはPWAとしてスマホ等で動作可能です。

Cloudflare Tunnelを使って自宅サーバーをポート開放せずに公開する
ポート開放等を行うのはセキュリティ的にリスクがあるので過去に紹介したCloudflare TunnelでのアクセスおよびCloudflare Accessでの認証を追加します。
設定方法に関しては前述の記事で解説していますのでOpenWebUIで利用した時の設定値のみ記載します。
Cloudflare Tunnelの設定
Public Host NameではサブドメインでAccess可能なように設定しています。Pathで設定するとOpenWebUIが開けないという話を聞いたりしてます。(再現確認はしていない)
Cloudflare Accessの設定
こちらは特筆すべきことはありません。
私はGoogle Workspaceアカウントを持ってますのでGoogle Workspaceアカウントを利用してインスタント認証を有効にして実質認証を知覚せずにアクセスできるようにしています。
まとめ
OpenWebUIとLiteLLMを導入するとUIの学習コストゼロで新しいLLMモデルを即時利用できるようになります。また過去のチャット履歴が1箇所に集まるためデータも見やすいです。
このように同じ質問を複数のLLMに投げて回答を比較することもできます。
またOllamaなどでローカルLLMを構築した際は閉じたネットワーク環境でも快適にLLM支援が受けられるようになります。
個人利用はもとよりオープンソースなため会社内サービスとしてデプロイするのも良いかと思います。全社員にChatGPT Plusのアカウントを配布するよりこれでChatGPTのAPIと繋ぎ込みして利用した方がトータルコストも恐らく安くなるでしょう。(会社利用という観点だと先日Google WorkspaceにGemini Advanceが追加されたのでコレでええやん説もありますが)
LiteLLMとOpenWebUIあわせてローカルPCのDockerで動かしてもリソースはあまり食いませんので気軽に利用してみてはいかがでしょうか。