「OllamaとOpen WebUIとNginxをバラバラにdocker runで管理していて、チームメンバーへ手順を共有しても再現できないと言われる」
そんな状況に直面しているLinuxサーバー管理者は少なくない。この記事では、OllamaとOpen WebUI・NginxをDocker Composeのマルチサービス構成にまとめる手順を解説する。
起動順制御・ネットワーク分離・ボリューム永続化・ヘルスチェックまでをYAML1ファイルに集約することで、
docker compose up -d一発で全サービスが立ち上がる再現性のある運用環境を構築する。GPUパススルーの設定方法と、運用でよく踏むトラブルの対処法も合わせて示す。
この記事のポイント
・Ollamaのhealthcheckとcondition: service_healthyでOpen WebUIの起動順を確実に制御できる
・networks.backend.internal: trueでOllamaを外部ネットワークから構成レベルで隔離できる
・GPUパススルーにはnvidia-container-toolkitとdaemon.jsonのランタイム設定が前提条件になる
・docker-compose.ymlをGitで管理すれば別サーバーでも完全再現できる環境になる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Docker ComposeでOllamaを一元管理する構成上のメリット
単体コンテナをdocker runで個別に起動する方法と比べて、Docker Composeには明確な利点がある。まず、サービス間の依存関係(depends_on)を宣言的に定義できる。OllamaのヘルスチェックがパスするまでOpen WebUIを起動しない、という起動順制御がYAMLで書けるため、手動での順序管理が不要になる。次に、ネットワーク分離が構成レベルで実現できる。Ollamaを内部ネットワーク専用に閉じ込め、外部にはNginx経由のポートだけ露出する設計が数行のYAMLで完結する。
さらに重要なのが再現性だ。
docker-compose.ymlとnginx.confをGitリポジトリで管理すれば、別サーバーでもgit clone後にdocker compose up -dだけで同一環境が立ち上がる。現場でよく聞く「手順書が古くてdocker runの引数が違っていて動かない」という問題が根本から解消される。なお、Ollamaのインストールや初回セットアップについてはUbuntu ServerでローカルLLMを構築する方法で詳しく解説しているので、環境を一から作る場合はそちらも参照してほしい。
前提条件と環境の確認
1. DockerとDocker Composeのバージョン確認
この記事はDocker Compose V2(docker composeサブコマンド形式)を前提とする。旧来のV1(docker-composeコマンド)とはYAML構文に差異があるため、バージョンを先に確認する。
$ docker --version Docker version 27.3.1, build ce12230 $ docker compose version Docker Compose version v2.29.7
Docker Compose version v2系であれば問題ない。V1のまま残っている環境はsudo apt install docker-compose-pluginでV2に移行する。
2. NVIDIA GPUドライバとnvidia-container-toolkitの確認
GPUを使ってLLM推論する場合、ホストに以下の2つが揃っている必要がある。$ nvidia-smi +-----------------------------------------------------------------------------+ | NVIDIA-SMI 550.120 Driver Version: 550.120 CUDA Version: 12.4 | |...(省略)... $ dpkg -l | grep nvidia-container-toolkit ii nvidia-container-toolkit 1.17.2-1 amd64
nvidia-container-toolkitが入っていない場合は以下でインストールする。
$ sudo apt install -y nvidia-container-toolkit $ sudo nvidia-ctk runtime configure --runtime=docker $ sudo systemctl restart docker
3. 作業ディレクトリの作成
$ mkdir -p ~/ollama-compose/nginx $ cd ~/ollama-compose
docker-compose.ymlの基本構成を作る
1. Ollamaサービスのみの最小構成
まずOllamaコンテナだけを定義した最小構成から始め、後続ステップでサービスを追加していく。# ~/ollama-compose/docker-compose.yml services: ollama: image: ollama/ollama:latest restart: unless-stopped ports: - "11434:11434" volumes: - ollama_models:/root/.ollama deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] volumes: ollama_models:
deploy.resources.reservations.devicesブロックがGPUパススルーの設定だ。CPUのみの環境ではこのブロックごと削除する。volumes.ollama_modelsで名前付きボリュームを定義することで、コンテナを削除・再作成してもモデルデータが消えない設計になる。ボリュームの実体は/var/lib/docker/volumes/ollama-compose_ollama_models/に保存される。
2. 起動と動作確認
$ docker compose up -d ollama $ curl http://localhost:11434/api/tags {"models":[]}
docker compose exec ollama ollama pull llama3.3:70b-instruct-q4_0で必要なモデルをダウンロードしておく。どのモデルを選ぶべきかはローカルLLMのモデルを比較する方法が参考になる。
Open WebUIコンテナを追加する
1. open-webuiサービスとヘルスチェックの定義
Open WebUIはGitHubコンテナレジストリ(ghcr.io)からイメージを取得する。OLLAMA_BASE_URL環境変数でOllamaコンテナのエンドポイントを指定するのがポイントだ。同時に、Ollamaサービスに
healthcheckを追加してOpen WebUIの起動順を制御する。
services: ollama: image: ollama/ollama:latest restart: unless-stopped volumes: - ollama_models:/root/.ollama deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] healthcheck: test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"] interval: 30s timeout: 10s retries: 5 start_period: 60s open-webui: image: ghcr.io/open-webui/open-webui:main restart: unless-stopped depends_on: ollama: condition: service_healthy environment: - OLLAMA_BASE_URL=http://ollama:11434 volumes: - open_webui_data:/app/backend/data ports: - "3000:8080" volumes: ollama_models: open_webui_data:
depends_on.ollama.condition: service_healthyが重要な設定だ。OllamaのヘルスチェックがパスするまでOpen WebUIコンテナの起動を待つため、「WebUIが起動したがOllamaにまだ繋がらない」という競合状態を防げる。http://ollama:11434というURLは、Dockerのサービスディスカバリーによりollamaコンテナへ名前解決される。コンテナ間通信では必ずサービス名を使い、IPアドレスには依存しない設計にする。
2. ブラウザでの動作確認
$ docker compose up -d $ docker compose ps NAME IMAGE STATUS ollama-compose-ollama-1 ollama/ollama:latest Up (healthy) ollama-compose-open-webui-1 ghcr.io/open-webui/open-webui Up
http://サーバーIP:3000でOpen WebUIにアクセスできる。初回アクセスでは管理者アカウント登録画面が表示されるので、管理者メールアドレスとパスワードを登録する。社内情報システムポリシーでクラウドAIが利用制限されている環境でのローカルLLM活用の背景については、社内でChatGPTが使えないときの代替手段も参照してほしい。
NginxリバースプロキシをDocker Composeに組み込む
Open WebUIのポート3000番を直接外部に公開するより、Nginxをフロントに置いてポート80番に統一する方が運用しやすい。WebSocketを使うチャット通信のタイムアウト設定も、Nginxで一元管理できる。1. nginx.confの作成
# ~/ollama-compose/nginx/nginx.conf upstream open_webui { server open-webui:8080; } server { listen 80; server_name _; client_max_body_size 100M; location / { proxy_pass http://open_webui; 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; # WebSocket対応(チャット通信に必須) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 300s; proxy_connect_timeout 75s; } }
proxy_read_timeout 300sはLLMの推論時間を考慮した設定だ。Nginxのデフォルトは60秒であり、70Bモデルで長い回答を生成している最中にタイムアウトが発生するケースが現場でよく報告される。
2. docker-compose.ymlにnginxサービスを追加する
nginx: image: nginx:stable-alpine restart: unless-stopped depends_on: - open-webui ports: - "80:80" volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
:ro(読み取り専用)でバインドマウントすることで、コンテナ内からの設定書き換えを防ぐ。このNginxをフロントに置いたことで、open-webuiのports: "3000:8080"設定は外部に公開する必要がなくなる。外部への窓口はNginxの80番のみに絞れる。
ネットワーク分離・ボリューム・ヘルスチェックの最終構成
1. 完成版docker-compose.yml
各サービスを内部ネットワーク(backend)と外部向けネットワーク(frontend)に分離した最終構成を示す。
services: ollama: image: ollama/ollama:latest restart: unless-stopped volumes: - ollama_models:/root/.ollama networks: - backend deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] healthcheck: test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"] interval: 30s timeout: 10s retries: 5 start_period: 60s open-webui: image: ghcr.io/open-webui/open-webui:main restart: unless-stopped depends_on: ollama: condition: service_healthy environment: - OLLAMA_BASE_URL=http://ollama:11434 volumes: - open_webui_data:/app/backend/data networks: - backend - frontend nginx: image: nginx:stable-alpine restart: unless-stopped depends_on: - open-webui ports: - "80:80" volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro networks: - frontend networks: backend: internal: true frontend: volumes: ollama_models: open_webui_data:
networks.backend.internal: trueがセキュリティ上の要点だ。internal: trueを設定したネットワークは、コンテナからインターネット方向への通信が遮断される。OllamaとOpen WebUI間の推論通信はこのバックエンドネットワーク内にとどまり、Ollamaの11434番ポートは外部に一切露出しない。外部への窓口はNginxのfrontendネットワーク経由のポート80のみになる。モデルデータや推論内容が外部に漏れるリスクをネットワーク設計として構成レベルで低減できる。
2. 設定変更後の更新手順
nginx.confを変更した場合は構文チェックを通してから再起動する。
# nginx設定の構文チェック $ docker compose exec nginx nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # nginxだけ再起動(他サービスは停止しない) $ docker compose restart nginx
docker-compose.yml自体を変更した場合はdocker compose up -dを再実行する。変更のあったサービスのコンテナだけが差し替えられ、他は影響を受けない。
Docker Composeを使った運用でよくあるトラブルと対処法
トラブル1: GPUがコンテナに認識されない
docker compose exec ollama nvidia-smiでエラーが返る場合、/etc/docker/daemon.jsonにnvidiaランタイムの設定が入っているか確認する。
$ cat /etc/docker/daemon.json { "runtimes": { "nvidia": { "args": [], "path": "nvidia-container-runtime" } } }
sudo nvidia-ctk runtime configure --runtime=dockerを実行してDockerを再起動する。daemon.jsonの設定がない状態では、docker-compose.ymlのdeploy.resources.reservations.devicesブロックが無視されるため、GPUがコンテナに見えない状態になる。
トラブル2: Open WebUIがOllamaに接続できない
ブラウザ上のOpen WebUIで「Ollamaに接続できません」と表示される場合、まずコンテナ間の疎通を確認する。$ docker compose exec open-webui curl http://ollama:11434/api/tags {"models":[...]}
http://ollama:11434に設定し直す。初期設定でlocalhostが入っているとコンテナ間通信が通らない。コマンドが失敗する場合は、ollamaとopen-webuiが同じbackendネットワークに属しているかを
docker network inspect ollama-compose_backendで確認する。internal: trueのネットワークではollama pullコマンド実行時にモデル取得が失敗する点にも注意が必要だ。モデル取得はollamaサービスのnetworksに一時的にfrontendも追加するか、先にモデルを取得してからinternal: trueに戻す手順を踏む。
トラブル3: モデルダウンロード後にディスクが枯渇する
70Bクラスのモデルは-q4_0量子化でも40GBを超えるケースがある。docker system df -vでボリュームの使用量を確認し、不要なモデルはdocker compose exec ollama ollama rm モデル名で削除する。ストレージが逼迫している場合は、OLLAMA_MODELS環境変数でモデル保存先を外付けHDDやマウントボリュームへ変更する方法が有効だ。
まとめ
OllamaをDocker Composeのマルチサービス構成にまとめることで、起動順管理・ネットワーク分離・設定の再現性という3つの課題を一括して解決できる。YAMLに全設定を集約してGitで管理すれば、チームへの展開も別サーバーへの移設もdocker compose up -d一発で済む。この記事の要点をまとめる。
| 操作 | コマンド | 備考 |
|---|---|---|
| 全サービス起動 | docker compose up -d |
依存順に自動起動。YAMLの変更後も同コマンドで差分更新 |
| サービス状態確認 | docker compose ps |
STATUS欄の「(healthy)」でヘルスチェック通過を確認 |
| モデル取得 | docker compose exec ollama ollama pull llama3.3:70b-instruct-q4_0 |
コンテナ内でollamaコマンドを実行 |
| モデル削除 | docker compose exec ollama ollama rm llama3.3:70b-instruct-q4_0 |
ディスク逼迫時に不要モデルを削除 |
| nginx設定反映 | docker compose restart nginx |
他サービスを止めずにnginxだけ再起動 |
| ログ確認 | docker compose logs -f ollama |
サービス名を指定して個別確認 |
| 全サービス停止 | docker compose down |
ボリュームは残る(モデルデータ保持) |
ローカルLLMのCompose本番構成を2日間で体験する
Docker ComposeでOllama・Open WebUI・Nginxをまとめて管理し、チームで安定稼働するローカルLLM環境を一から構築する。そのプロセスを実機で体験してみたい方は多いはずだ。実機GPU環境で手を動かしながら習得したい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。
・Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド
・社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢
・ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:OllamaとTelegramボットを連携させる方法|ローカルLLMをスマートフォンからチームで安全に使う手順
- この記事の属するカテゴリ:ローカルLLMへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます