Docker ComposeでOllamaをGPUと永続的なモデルストレージ付きで運用する

GPUと永続化対応のコンポーズファーストOllamaサーバー。

目次

Ollama はベアメタル上で非常に良好に動作します。サービスとして扱うようになると、さらに興味深いものになります。安定したエンドポイント、ピン留めされたバージョン、永続化ストレージ、そして利用可能かどうかの明確な GPU。

この記事では、Docker Compose を使用して、GPU アクセラレーションとモデルの永続化ストレージを備えた、再現可能なローカルまたは単一ノードの Ollama「サーバー」という 1 つの目標に焦点を当てます。

ollama docker compose

一般的な Docker と Compose の基礎は意図的に省略しています。最も頻繁に使用するコマンド(イメージ、コンテナ、ボリューム、docker compose など)の簡潔な一覧が必要な場合、Docker チートシート が良い相棒になります。

Ollama の前に HTTPS を設定し、正しいストリーミングと WebSocket プロキシング、およびエッジコントロール(認証、タイムアウト、レート制限)が必要な場合、Caddy または Nginx を使用したリバースプロキシの背後にある Ollama による HTTPS ストリーミング. を参照してください。

Ollama が vLLM、Docker Model Runner、LocalAI、およびクラウドホスティングのトレードオフとどのように並ぶかについては、 2026 年の LLM ホスティング:ローカル、セルフホステッド & クラウドインフラストラクチャの比較. をご覧ください。

この Compose スタックが実際の並列トラフィックを処理し始めると、次の質問は、その下層エンジンとして Ollama が依然として最適な選択肢かどうかであることがよくあります。Ollama から vLLM への移行:ローカル LLM サーバーを移行すべきタイミング. は、検証中に両方のコンテナを並列で実行し続ける段階的な移行パスを示しています。

Compose がベアメタルインストールに勝つ場合

ネイティブインストールは、1 人の開発者が 1 台のマシンを使用する場合、摩擦がありません。以下のいずれかの状況が発生した瞬間に、Compose は使い勝手の面で優位に立ち始めます。

チームセットアップでは、サービス定義がレビュー、バージョン管理、共有できるファイルであるため、利点があります。単一ノードサーバーでは、アップグレードがイメージタグの更新と再起動に変わり、モデルストレージはそのまま保持されるため(ボリューム上にありさえすれば)、利点があります。Ollama はまた、サイドカーの近くに住む傾向があります:Web UI、リバースプロキシ、認証ゲートウェイ、ベクトル DB、またはエージェントランタイム。Compose は「1 つのコマンドでスタック全体を開始する」ことに長けており、ホストをユニーク(snowflake)なものに変えることなく実現します。

このアプローチは、公式 Ollama コンテナの設計とよく合致しています:イメージはデフォルトで ollama serve を実行し、ポート 11434 を公開し、マウント可能なディレクトリ下に状態を保持するように意図されています。ollama serve が読み取る OLLAMA_* 環境変数の完全なセット — OLLAMA_HOST、OLLAMA_CONTEXT_LENGTH、OLLAMA_KEEP_ALIVE、OLLAMA_NUM_PARALLEL およびその他 — は Ollama CLI チートシート. に記載されています。

Ollama に実際に役立つ Compose スケルトン

まず、2 つの決定から始めましょう:

第一に、バージョンをどのようにピン留めするか。Docker Hub イメージは ollama/ollama なので、latest に頼るのではなく、.env で特定のタグをピン留めできます。

第二に、モデルデータがどこに配置されるか。公式ドキュメントでは、コンテナが置換されるたびにモデルを再ダウンロードしないように、ボリュームを /root/.ollama にマウントします。

それらの決定を組み込み、サービスに近い位置に「調整可能な項目(ノブ)」を保持する Compose ファイルを以下に示します:

services:
  ollama:
    image: ollama/ollama:${OLLAMA_IMAGE_TAG:-latest}
    container_name: ollama
    restart: unless-stopped

    # デフォルトではローカルに保持し、必要に応じて後に公開します。
    ports:
      - "${OLLAMA_BIND_IP:-127.0.0.1}:11434:11434"

    # 永続的なモデルとサーバー状態。
    volumes:
      - ollama:/root/.ollama

    environment:
      # 公式イメージは既にコンテナ内で 0.0.0.0:11434 がデフォルトですが、
      # 後でオーバーライドする場合に備えて明示的にしておくと便利です。
      - OLLAMA_HOST=0.0.0.0:11434

      # サービスのチューニング。
      - OLLAMA_KEEP_ALIVE=${OLLAMA_KEEP_ALIVE:-5m}
      - OLLAMA_NUM_PARALLEL=${OLLAMA_NUM_PARALLEL:-1}
      - OLLAMA_MAX_LOADED_MODELS=${OLLAMA_MAX_LOADED_MODELS:-1}

      # 任意ですが、ブラウザベースの UI が Ollama に直接通信する場合に関連します。
      # なぜこれが存在するのかについては、ネットワークセクションを参照してください。
      - OLLAMA_ORIGINS=${OLLAMA_ORIGINS:-}

    # GPU 予約は下のセクションにあります。
    # 実際の NVIDIA GPU を備えたホストでのみ追加してください。

volumes:
  ollama: {}

対応する .env を使用すると、アップグレードは地味なものになります:

# テスト済みのイメージバージョンをピン留めします。
OLLAMA_IMAGE_TAG=latest

# デフォルトではローカルです。意図的に公開する場合は 0.0.0.0 に変更します。
OLLAMA_BIND_IP=127.0.0.1

# キープアライブは、コールドスタートの遅延とメモリフットプリントのバランスを調整します。
OLLAMA_KEEP_ALIVE=5m

# 並列処理のノブ。
OLLAMA_NUM_PARALLEL=1
OLLAMA_MAX_LOADED_MODELS=1

# ブラウザクライアントが Ollama に直接アクセスする場合以外はいったん空にしておきます。
OLLAMA_ORIGINS=

小さくて重要なニュアンス:Ollama 自体は一般的な設定でデフォルトのホストバインドが 127.0.0.1:11434 ですが、公式コンテナイメージは OLLAMA_HOST=0.0.0.0:11434 を設定しており、公開されたポートを通じてサービスに到達できるようにしています。

クライアント SDK を使用せずに、素早い健全性確認を行いたい場合、Ollama API には GET /api/tags に「ローカルモデルの一覧」エンドポイントが含まれています。

永続的なモデルストレージと、移動時の最も痛みが少ない方法

1 つだけ覚えていれば、それはこれです:コンテナには永続ストレージが必要であり、そうしないと、再構築のたびに再ダウンロードが発生します。

Ollama は、OLLAMA_MODELS を使用してモデルディレクトリを選択できます。リファレンス実装では、デフォルトは $HOME/.ollama/models であり、OLLAMA_MODELS を設定するとそれが上書きされます。

公式 Docker イメージ内では、$HOME はドキュメント化されたボリュームマウント(/root/.ollama)で使用する /root レイアウトに自然にマッピングされるため、公式の docker run の例がそのディレクトリをマウントする理由がまさにここにあります。

実務的にうまくいく 2 つのストレージパターンがあります:

名前付き Docker ボリュームは最もシンプルでポータブルです。しかし、意図せず孤児化しやすいので、意図的に名前を付ける(例えば ollama など)ことが価値があり、Compose のリファクタリングを通じてそれを安定させておくべきです。

モデルサイズがルートファイルシステムを支配し始めるときは、専用のディスクへのバインドマウントがより適しています。その場合、全体 /root/.ollama をそのディスクにマウントするか、カスタムディレクトリをマウントして OLLAMA_MODELS をそれに指し合わせるかのいずれかです。

ストレージを積極的に再編成している場合、明示的な「モデルの移動」プレイブックが役立ちます。参照:move-ollama-models .

Compose と NVIDIA Container Toolkit による NVIDIA GPU サポート

Ollama は Docker で NVIDIA GPU を使用できますが、イメージが GPU を魔法のように出現させることはできません。ホストに動作する NVIDIA ドライバーと NVIDIA Container Toolkit が必要であり、Docker がそれを使用するように設定されている必要があります。Ollama の Docker ドキュメントは、nvidia-container-toolkit のインストール、nvidia-ctk runtime configure --runtime=docker によるランタイムの設定、および Docker の再起動を明示的に指摘しています。

Compose 側では、クリーンでモダンな方法はデバイス予約です。Docker は deploy.resources.reservations.devices を使用して Compose での GPU アクセスをドキュメント化しており、capabilities: [gpu]、driver: nvidia、および count(all を含む)または device_ids のいずれかを使用します。

NVIDIA ホスト上で ollama サービスにこれを追加します:

deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          count: all
          capabilities: [gpu]

複数の GPU を持有し、Ollama を特定のデバイスに保持したい場合は、Docker がドキュメント化しているように count から device_ids に切り替えます(これらは互いに排他的です)。

時に、レガシーの Compose サンプルでは runtime: nvidia が使用されます。新しいセットアップでは、“unknown or invalid runtime name: nvidia” のようなエラーが発生する可能性があるため、サポートされているデバイス予約パターンに移行し、ホストでツールキットが設定されていることを確認すべきです。

目に留まりにくい有用な詳細:公式 ollama/ollama イメージは NVIDIA_VISIBLE_DEVICES=all と NVIDIA_DRIVER_CAPABILITIES=compute,utility を設定しています。これらは NVIDIA コンテナランタイムによって認識される標準的なノブであり、上書きしない限り既に存在します。

GPU 推論を実際に得ているかどうかを確認するためには(コンテナが起動するだけではない)、Ollama は ollama ps を使用し、モデルが GPU メモリ上にあるかどうかを示す「Processor」列を確認することを推奨しています。

プラットフォームの実態確認:Ollama は、Docker での GPU アクセラレーションは Linux(および WSL2 を備えた Windows)で利用可能であり、GPU パススルーの欠如により、macOS 向け Docker Desktop では利用不可であると注記しています。

ネットワークの選択肢:ホスト対ブリッジ、ポート、および CORS

ネットワークは、ほとんどの「動作はするがアプリが接続できない」というバグの原因です。

公開ポートによるブリッジネットワーク

デフォルトの Compose ネットワークはブリッジネットワークです。このセットアップでは、11434:11434 を公開することで、ホストからポート 11434 で Ollama に到達できるようになりますが、他のコンテナはサービス名 ollama(localhost ではなく)を使ってそれと通信する必要があります。localhost はコンテナ内で「このコンテナ」を意味し、「Ollama コンテナ」を意味しないため、多くの人がここでつまずきます。

Ollama 自体はポート 11434 で HTTP サーバーを実行します(イメージがそれを公開しており)、一般的にポートが公開されている場合、クライアントはホスト上で http://localhost:11434 を使用する慣習があります。

ホストネットワーク

単一ノードサーバーでは、network_mode: host はポートの公開を除去し、localhost のセマンティクスを単純にするため魅力的に感じられるかもしれません。トレードオフは、ブリッジネットワークの分離とネームスペース化の利点を失うことと、ポート競合に遭遇する可能性が高くなることです。

意図的な Ollama の公開

通常のインストールでの Ollama はデフォルトで 127.0.0.1 にバインドし、バインドアドレスを変更するドキュメント化された方法は OLLAMA_HOST です。

Docker では、2 つのレイヤーがあります:

OLLAMA_HOST によって制御される Ollama バインドアドレス(コンテナイメージはデフォルトでコンテナ内のすべてのインターフェースにバインドする)。

コンテナの外からの到達可能性は、Compose の ports とホストファイアウォールによって制御される。

私が好むパターンは、127.0.0.1:11434:11434 による「デフォルトではローカルにバインド」し、公開する理由がある場合のみ 0.0.0.0:11434:11434 に切り替えることです。

ブラウザクライアントと OLLAMA_ORIGINS

ブラウザベースの UI または拡張機能が Ollama に直接呼び出しを行う場合、CORS の領域に入ります。Ollama はデフォルトで 127.0.0.1 と 0.0.0.0 からのクロスオリジンリクエストを許可し、OLLAMA_ORIGINS を使用して追加のオリジンを設定できます。

これは単一ノードでも重要であり、「curl で動作する」ことは「ブラウザアプリで動作する」ことを意味しません。

単一ノードサーバーに適したアップグレードとロールバックのパターン

Ollama は速く進化します。Compose ファイルにより、それが深夜の驚きではなく、落ち着いたプロセスに変わります。

“latest” の動作を祈るのではなく、タグの更新によるアップグレード

最も実用的なアップグレード戦略は、テスト済みの既知のタグにイメージをピン留めし、意図的に更新することです。イメージは Docker Hub で ollama/ollama として公開されています。

モデルデータとサーバー状態がマウントされたディレクトリ(公式ドキュメントでは /root/.ollama)の下に保存されるため、コンテナの置換はモデルの再ダウンロードを意味しません。

ロールバックはタグを元に戻すだけです

ロールバックは逆の同じメカニズムです:以前のタグを設定し、コンテナを再作成し、同じボリュームを保持します。ここでピン留めの価値が支払われます。

データマイグレーションは主にストレージパスに関するものです

単一ノードセットアップでのほとんどの「マイグレーション」はデータベーススキーマではなく、ディスクレイアウトに関するものです。モデルディレクトリ(OLLAMA_MODELS を通じて)を変更するか、マウントされたボリュームを新しいディスクに移動する場合、そう呼ぼうとも呼ぶまいと、それはデータマイグレーションです。

実際のマシンでのモデルディレクトリの再編成に関する実用的なガイドが欲しい場合、参照:move-ollama-models .

見逃しがちな最後の注記:Ollama の API ドキュメントは、API が安定しており後方互換であることが期待され、まれな非推奨はリリースノートで通告されることを明示しています。これにより、「サーバーをアップグレードし、クライアントを動作のままにしておく」は、単一ノードサービスエンドポイントにとって合理的なデフォルトの期待になります。

一般的な失敗:GPU 権限、ドライバー不一致、および OOM

このセクションは意図的に症状駆動型です。目標は「考え得るすべての Docker エラー」ではなく、Ollama + GPU + 永続ストレージセットアップで特に顕在化する失敗だけです。

ホストには GPU が見えるが、コンテナには見えない

ホストに動作する NVIDIA ドライバーがあっても、コンテナが GPU を見ない場合、一般的な原因は以下の通りです:

NVIDIA Container Toolkit がインストールされていない、または nvidia-ctk 経由で Docker ランタイムが設定されていないこと。Ollama の Docker ドキュメントはこれを直接指摘しています。

Compose が GPU デバイスを予約していないこと。Docker がドキュメント化しているサポートされている方法は、gpu ケイパビリティを備えた deploy.resources.reservations.devices です。

レガシーの runtime: nvidia 設定がそれを認識しないデーモンで使われ、“unknown or invalid runtime name: nvidia” が生成されること。

検証のため、ollama ps は実用的なチェックを提供します:モデルが GPU メモリにロードされているかどうかを示します。

GPU デバイスへのアクセス拒否

「permission denied」の種類の GPU 失敗は、通常、Ollama 自体ではなく環境制約を指しています。例には、rootless Docker の実行、セキュリティポリシー、またはデバイスノードが想定通りに公開されていないことが含まれます。Docker Compose GPU サポートドキュメントは、ホストに GPU デバイスがなければならないこと、および Docker デーモンがそれに応じて設定されていなければならないことを明示しています。

疑わしい場合は、変数を減らします:ツールキットの設定(ホスト)を確認し、次に GPU 予約(Compose)を確認し、次に GPU 使用状況(ollama ps)を確認します。

誤ったドライバー、誤った期待

Docker 上の Ollama はホストのドライバースタックに依存しています。ホストドライバーが欠落、古すぎ、または設定不備の場合、Ollama が壊れているように見えるが実際は「CUDA スタックが使えない」という失敗が見えます。公式ドキュメントは、NVIDIA GPU 使用の前提条件として、コンテナツールキットと Docker デーモンの設定を位置づけています。

メモリ不足:VRAM または RAM が急速に消える

OOM(メモリ不足)はローカル推論で最も予測可能な失敗モードであり、通常は設定による自己招致です。

Ollama は、複数のロード済みモデルと並列リクエスト処理による並列処理をサポートしますが、利用可能なメモリ(CPU 推論ではシステム RAM、GPU 推論では VRAM)によって制約されます。GPU 推論が使用される場合、並列モデルロードを許可するには、新しいモデルが VRAM に収まる必要があります。

2 つの設定の詳細は、「サーバー設定」として第一級のものとして扱う価値があります:

OLLAMA_NUM_PARALLEL はモデルごとの並列リクエスト処理を増加させますが、必要なメモリは OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH に従ってスケールします。

OLLAMA_KEEP_ALIVE はモデルがロードされたままになる時間を制御します(デフォルトは 5 分)。モデルをロードしたままにすることはコールドスタートの遅延を減らしますが、メモリを固定します。

負荷下で単一ノードサービスを安定させている場合、劇的でない修正は通常以下のように見えます:

他のものを 변경する前に、並列性とコンテキストのデフォルトを下げます。

同時にロードされたままに許可されるモデルの数を制限します。

ボトルネックが生粋の計算力ではなくメモリである場合、Flash Attention(OLLAMA_FLASH_ATTENTION=1)や低精度の K/V キャッシュタイプ(OLLAMA_KV_CACHE_TYPE)などのメモリ削減機能を検討します。

それが Ollama でない場合:Docker Model Runner への選択

時に、「失敗」は実際にはツールミスマッチです。あなたの組織がすでに Docker ネイティブの成果物とワークフローを標準化している場合、Ollama を長期間生存するサービスコンテナとして実行するよりも、Docker Model Runner(DMR)の方が良いフィットになることがあります。

Docker は、Docker を直接使用してモデルを管理、実行、サーブする方法として DMR を位置づけ、Docker Hub または他の OCI レジストリから取得し、OpenAI 互換および Ollama 互換の API をサーブします。

また、複数の推論エンジン(llama.cpp を含む、Linux で NVIDIA GPU を使用した vLLM など)をサポートしており、ローカルで 1 つのモデルを実行するだけでなく、スループット特性に関心がある場合は重要になり得ます。

実用的なコマンドリファレンスとより深い比較の角度が欲しい場合、参照:Docker Model Runner チートシート:コマンドと例.

購読する

システム、インフラ、AIエンジニアリングの新記事をお届けします。