はじめに
前回の記事では、WSL2にRocky Linuxを入れてDocker環境を構築しました。
今回はその環境を使って、ローカルで動くAI基盤を構築します。仕事でオンプレのAI基盤構築に関わっているので、その練習も兼ねて試してみました。同じような環境の方の参考になれば幸いです。
構成はこんなイメージです:
ブラウザ → Nginx(80) → Open WebUI(8080) → Ollama(11434)
- Ollama: LLMの推論エンジン。モデルの管理・実行を担当
- Open WebUI: ChatGPTライクなチャットUI
- Nginx: リバースプロキシ。外部からのアクセスをOpen WebUIに転送
この記事でできること
| 項目 | 内容 |
|---|---|
| 所要時間 | 約20分(回線速度による) |
| 環境 | WSL2 + Rocky Linux 9 + Docker Engine |
| 対象 | ローカルLLM環境を試したい方 |
前回の記事の環境が前提となります。まだの方は先にそちらをご覧ください。
環境
- Rocky Linux 9.7 (Blue Onyx)
- Docker Engine 29.2.1
- Ollama latest
- Open WebUI latest
- Nginx latest
- モデル: llama3.2:1b
なぜNginxをリバースプロキシに置くのか
手順に入る前に、Nginxを挟む理由を簡単に説明します。
Nginxなしの場合、各サービスのポートを直接指定してアクセスする必要があります。
Open WebUI: http://localhost:3000
Ollama API: http://localhost:11434
Nginxをリバースプロキシとして置くことで:
-
ポート管理がシンプルになる: すべて
http://localhostでアクセスできる - SSL終端を一箇所にまとめられる: 本番環境でHTTPS化する際にNginxだけ設定すればよい
- セキュリティ向上: バックエンドのサービスを外部に直接露出しなくて済む
オンプレ基盤構築の現場でもよく見る構成なので、練習として取り入れました。
手順
1. 作業ディレクトリの作成
mkdir ~/ollama && cd ~/ollama
2. docker-compose.ymlの作成
cat <<EOF > docker-compose.yml
# Ollama + Open WebUI + Nginx 構成
# ブラウザ → Nginx(80) → Open WebUI(8080) → Ollama(11434)
services:
# LLM推論エンジン
ollama:
image: ollama/ollama:latest
container_name: ollama
ports:
- "11434:11434"
volumes:
# モデルデータの永続化
- ollama_data:/root/.ollama
# チャットUI
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
expose:
- "8080"
environment:
# OllamaのAPIエンドポイント(コンテナ名で名前解決)
- OLLAMA_BASE_URL=http://ollama:11434
volumes:
# WebUIのデータ永続化
- webui_data:/app/backend/data
depends_on:
- ollama
# リバースプロキシ
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
volumes:
# Nginx設定ファイルをマウント
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- open-webui
volumes:
ollama_data:
webui_data:
EOF
各サービスに container_name を指定しています。これにより、作業ディレクトリ名に関わらずコンテナ名が固定され、後続の docker exec コマンドが常に同じ名前で実行できます。
3. nginx.confの作成
cat <<EOF > nginx.conf
# Open WebUI へのリバースプロキシ設定
server {
# 80番ポートでリッスン
listen 80;
location / {
# Open WebUIコンテナへ転送
proxy_pass http://open-webui:8080;
# 実際のクライアント情報をヘッダーに付与
# \$host などの \$ はシェルでの変数展開を防ぐためのエスケープ
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
# WebSocketのサポート(Open WebUIのリアルタイム通信に必要)
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
}
}
EOF
4. ファイルの確認
ls -la
以下の2ファイルが存在すればOKです。
docker-compose.yml
nginx.conf
5. コンテナの起動
docker compose up -d
初回はイメージのダウンロードがあるため、回線速度によっては10〜15分程度かかります。
起動確認:
docker ps
3つのコンテナ(ollama、open-webui、nginx)が Up になっていれば成功です。
6. LLMモデルのダウンロード
コンテナが起動したら、Ollamaコンテナ内でモデルをダウンロードします。
docker exec -it ollama ollama pull llama3.2:1b
モデルのメモリ目安
| モデル | 必要メモリ | 速度 |
|---|---|---|
| llama3.2:1b | 約1GB | ◎ |
| llama3.2:3b | 約2GB | ○ |
| mistral:7b | 約4GB | △ |
GPUなしのCPU推論の場合、大きなモデルはレスポンスが遅くなります。まずは llama3.2:1b から試すのがおすすめです。
WSL2 + DockerでもNVIDIA Container Toolkitを導入することでGPU推論が可能になります。より高速な推論を試したい場合はこちらも検討してみてください。
7. 動作確認
ブラウザで以下にアクセスします。
http://localhost
Open WebUIのログイン画面が表示されたら成功です。アカウントを作成してログインし、モデルに話しかけてみてください。
よくあるハマりどころ
WebSocketエラーが出る場合
nginx.confの以下の2行が抜けているとリアルタイム通信が動作しません。
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
まとめ
Docker上にOllama + Open WebUI + Nginxを使ったローカルAI基盤を構築する手順を紹介しました。
GPUなしのCPU推論なのでレスポンスは遅めですが、構成の理解や練習としては十分な環境です。NVIDIA Container Toolkitを導入すればWSL2上でもGPU推論が可能になるので、さらに高速化したい場合はぜひ試してみてください。
次回はこの環境にPrometheus + Grafanaを追加してコンテナ監視基盤を構築する手順を紹介します。
参考
この記事はClaude(Anthropic)を活用して作成しました。