Ollama: Dockerコンテナデプロイ

DockerはOllamaをLEGOブロックに変える——イメージをプル、組み合わせ、1コマンドでデプロイ。

⚠️ : Dockerコンテナはデフォルトでデータを永続化しない——コンテナを削除するとすべてのモデルファイル(数GBになることが多い)が失われる。Volumeマウント(-v ollama_data:/root/.ollama)でモデルデータをホストに永続化すること。本番環境ではこれを絶対に省略してはならない。

📋 前提条件: まず以下を習得していること

1. 学べること


2. SaaS起業家のリアルな事例

(1) ペインポイント:毎回のサーバーでOllamaを手動インストール

AliceはSupportBotを3台のサーバーにデプロイする必要があり、各サーバーでOllamaのインストール、モデルのプル、環境設定を手動で行う必要がある。バージョンの不整合、設定漏れ、環境の差異が様々な問題を引き起こす。

(2) ソリューション:1コマンドDockerデプロイ

BASH
# One command to run Ollama in container
docker run -d --gpus all -v ollama_data:/root/.ollama ollama/ollama

# Or with Docker Compose for full stack
docker compose up -d

3. 公式Ollamaイメージ

(1) イメージバリエーション

イメージ サイズ 用途
ollama/ollama ~800 MB CPU + GPU(自動検出)
ollama/ollama:rocm ~1.2 GB AMD GPUのみ

(2) 基本実行コマンド

シナリオ コマンド
CPUのみ docker run -d -p 11434:11434 ollama/ollama
NVIDIA GPU docker run -d --gpus all -p 11434:11434 ollama/ollama
永続ストレージ docker run -d -v ollama_data:/root/.ollama -p 11434:11434 ollama/ollama
カスタムポート docker run -d -p 8080:11434 ollama/ollama
100%
flowchart TD
    A[ollama/ollamaイメージ] --> B{GPUあり?}
    B -->|NVIDIA| C[nvidia-container-toolkit<br/>--gpus all]
    B -->|AMD| D[rocmイメージ<br/>--device /dev/kfd]
    B -->|なし| E[CPUのみモード]
    C --> F[Ollamaサーバー :11434]
    D --> F
    E --> F

(3) ▶ サンプル:CPUコンテナ実行

⚠️ 警告: Volumeマウント(-v ollama_data:/root/.ollama)なしでコンテナを実行すると、モデルデータはコンテナ内に保存される。コンテナを削除するとすべてのモデルが失われ、再ダウンロード(数GB)が必要。本番環境では必ず永続ストレージをマウントすること。

BASH
# Run Ollama in container (CPU mode)
docker run -d \
  --name ollama \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama

# Verify it's running
docker ps | grep ollama

# Pull a model inside the container
docker exec ollama ollama pull qwen2.5

# Test the API
curl http://localhost:11434/api/tags

出力:

TEXT
I'm a helpful AI assistant running locally on your machine...

4. GPUコンテナ設定

(1) NVIDIA GPUコンテナ前提条件

ステップ コマンド 説明
1 NVIDIAドライバーのインストール nvidia-smiが動作すること
2 nvidia-container-toolkitのインストール GPUパススルーに必要
3 Dockerの再起動 sudo systemctl restart docker
4 GPU可用性確認 docker run --rm --gpus all nvidia/cuda:12.0.0-runtime-ubuntu22.04 nvidia-smi

(2) nvidia-container-toolkitのインストール

プラットフォーム インストールコマンド
Ubuntu/Debian `curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey
CentOS/RHEL `curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo
Docker設定 sudo nvidia-ctk runtime configure --runtime=docker && sudo systemctl restart docker

(3) ▶ サンプル:NVIDIA GPUコンテナ実行

BASH
# Run Ollama with GPU support
docker run -d \
  --name ollama-gpu \
  --gpus all \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama

# Verify GPU is visible inside container
docker exec ollama-gpu nvidia-smi

# Test GPU inference speed
docker exec ollama-gpu ollama run --verbose llama3.2 "Hello"

# Specify which GPUs to use
docker run -d \
  --gpus '"device=0,1"' \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama

出力:

TEXT
I'm a helpful AI assistant running locally on your machine...

(4) ▶ サンプル:AMD ROCmコンテナ

BASH
# Run Ollama with AMD GPU (ROCm)
docker run -d \
  --name ollama-rocm \
  --device /dev/kfd \
  --device /dev/dri \
  -p 11434:11434 \
  -v ollama_data:/root/.ollama \
  ollama/ollama:rocm

出力:

TEXT
I'm a helpful AI assistant running locally on your machine...

5. Docker Composeマルチサービスオーケストレーション

💡 ヒント: Docker Composeは1コマンドで複数サービスをオーケストレーション可能(Ollama + Chroma + WebUI + FastAPI)。healthcheck + depends_on.condition: service_healthyを使用すると、下流サービスの起動前に上流サービスが本当に準備完了であることを保証でき、単純な起動順序より信頼性が高い。

💡 ヒント: Docker Composeのhealthcheck + depends_on.condition: service_healthyは、下流サービスの起動前に上流サービスが本当に準備完了であることを保証し、単純な起動順序より信頼性が高い。Ollamaは起動後数秒経たないとAPIリクエストに応答できない。

(1) 典型的なマルチサービスアーキテクチャ

100%
flowchart TD
    A[Nginx<br/>:80 リバースプロキシ] --> B[FastAPIアプリ<br/>:8000]
    B --> C[Ollama<br/>:11434]
    B --> D[Chroma DB<br/>:8001 ベクトルストア]
    C --> E[モデルボリューム]
    D --> F[Chromaボリューム]

(2) docker-compose.ymlテンプレート

サービス イメージ ポート 依存関係
ollama ollama/ollama 11434 GPUランタイム
webui open-webui/open-webui 3000 ollama
chroma chromadb/chroma 8000
app カスタムfastapi 8001 ollama, chroma

(3) ▶ サンプル:完全Docker Compose設定

⚠️ 警告: 本番設定でOLLAMA_HOST=0.0.0.0:11434にすると、Ollamaがすべてのネットワークインターフェースでリッスンする。Docker内部ネットワーク内では安全だが、ポートがホストのパブリックIPにマッピングされている場合は極めて危険。必ずNginx認証またはファイアウォールルールと組み合わせて使用すること。

YAML
# docker-compose.yml
version: "3.8"

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    restart: unless-stopped

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - webui_data:/app/backend/data
    depends_on:
      - ollama
    restart: unless-stopped

  chroma:
    image: chromadb/chroma
    container_name: chroma
    ports:
      - "8001:8000"
    volumes:
      - chroma_data:/chroma/chroma
    environment:
      - ANONYMIZED_TELEMETRY=FALSE
    restart: unless-stopped

volumes:
  ollama_data:
  webui_data:
  chroma_data:
BASH
# Start all services
docker compose up -d

# Pull model inside ollama container
docker exec ollama ollama pull qwen2.5
docker exec ollama ollama pull nomic-embed-text

# Check all services
docker compose ps

# View logs
docker compose logs -f ollama

出力:

TEXT
[+] Running 4/4
 ✔ Network ollama_default  Created
 ✔ Container ollama        Started
 ✔ Container open-webui    Started
 ✔ Container chroma        Started

(1) Volumeマウント比較

方式 コマンド 永続性 パフォーマンス
名前付きボリューム -v ollama_data:/root/.ollama ✅ Docker管理 良好
バインドマウント -v /data/ollama:/root/.ollama ✅ ホスト管理 最高
tmpfs --tmpfs /root/.ollama ❌ メモリのみ 最速

(2) ネットワークモード比較

モード コマンド ユースケース 説明
bridge デフォルト コンテナ間通信 ポートマッピングが必要
host --network host 低レイテンシ ホストネットワークを共有
カスタムネットワーク docker network create mynet マルチサービス 自動DNS解決

(3) ▶ サンプル:本番グレードDocker Compose

YAML
# docker-compose.prod.yml
version: "3.8"

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - /data/ollama/models:/root/.ollama
    environment:
      - OLLAMA_HOST=0.0.0.0:11434
      - OLLAMA_KEEP_ALIVE=30m
      - OLLAMA_NUM_PARALLEL=4
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
        limits:
          memory: 16G
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
      interval: 30s
      timeout: 10s
      retries: 3

  app:
    build: ./app
    container_name: supportbot
    ports:
      - "8000:8000"
    environment:
      - OLLAMA_HOST=http://ollama:11434
    depends_on:
      ollama:
        condition: service_healthy
    restart: unless-stopped

networks:
  default:
    name: supportbot-net

出力:

TEXT
# Verify configuration file syntax
docker compose config --quiet && echo "✅ Configuration file syntax is correct"
# Output: ✅ Configuration file syntax is correct

7. 総合サンプル:SupportBotフルスタックDockerデプロイ

ℹ️ 情報: init-modelsコンテナは「1回限りタスク」パターンを使用——Ollamaのヘルスチェック通過後に必要なモデルを自動的にプルし、その後終了する。これによりコンテナに入って手動でollama pullを実行する必要がなくなり、真の「1コマンドデプロイ」を実現。

YAML
# ============================================
# Comprehensive: SupportBot full-stack Docker
# Ollama + FastAPI + Chroma + Open WebUI
# ============================================

# docker-compose.yml
version: "3.8"

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_models:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:11434/api/tags || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
    restart: unless-stopped

  init-models:
    image: curlimages/curl
    container_name: init-models
    depends_on:
      ollama:
        condition: service_healthy
    command: >
      sh -c "
        curl -s http://ollama:11434/api/pull -d '{\"name\":\"qwen2.5\"}' &&
        curl -s http://ollama:11434/api/pull -d '{\"name\":\"nomic-embed-text\"}' &&
        curl -s http://ollama:11434/api/pull -d '{\"name\":\"llava\"}'
      "

  chroma:
    image: chromadb/chroma
    container_name: chroma
    ports:
      - "8001:8000"
    volumes:
      - chroma_data:/chroma/chroma
    environment:
      - ANONYMIZED_TELEMETRY=FALSE
    restart: unless-stopped

  supportbot:
    build:
      context: ./app
      dockerfile: Dockerfile
    container_name: supportbot
    ports:
      - "8000:8000"
    environment:
      - OLLAMA_HOST=http://ollama:11434
      - CHROMA_HOST=http://chroma:8000
      - EMBED_MODEL=nomic-embed-text
      - CHAT_MODEL=qwen2.5
    depends_on:
      ollama:
        condition: service_healthy
      chroma:
        condition: service_started
    restart: unless-stopped

  webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: webui
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - webui_data:/app/backend/data
    depends_on:
      - ollama
    restart: unless-stopped

volumes:
  ollama_models:
  chroma_data:
  webui_data:
BASH
#!/bin/bash
# Deploy SupportBot stack

# Start all services
docker compose up -d

# Wait for Ollama to be healthy
echo "Waiting for Ollama to be ready..."
until curl -s http://localhost:11434/api/tags > /dev/null 2>&1; do
    sleep 2
done
echo "Ollama is ready!"

# Pull required models
docker exec ollama ollama pull qwen2.5
docker exec ollama ollama pull nomic-embed-text

# Verify all services
docker compose ps
echo "SupportBot stack deployed!"
echo "  Ollama API:  http://localhost:11434"
echo "  SupportBot:  http://localhost:8000"
echo "  WebUI:       http://localhost:3000"
echo "  Chroma:      http://localhost:8001"

出力:

TEXT
Waiting for Ollama to be ready...
Ollama is ready!
NAME                IMAGE                              STATUS
ollama              ollama/ollama                      Up (healthy)
chroma              chromadb/chroma                    Up
supportbot          custom/app                         Up
webui               ghcr.io/open-webui/open-webui      Up
SupportBot stack deployed!
  Ollama API:  http://localhost:11434
  SupportBot:  http://localhost:8000
  WebUI:       http://localhost:3000
  Chroma:      http://localhost:8001

❓ よくある質問

Q Dockerコンテナ内のGPU推論は直接インストールより遅い?
A 通常は差がないはず。確認:1)--gpus allが有効か;2)nvidia-container-toolkitがインストールされているか;3)Dockerランタイムがnvidiaに設定されているか。
Q コンテナ再起動後もモデルは残っている?
A /root/.ollamaにVolumeをマウントしていれば、モデルデータは永続化されて残る。Volumeなしだとモデルは失われ、再プルが必要。
Q コンテナに入ってollamaコマンドを実行するには?
A docker exec -it ollama bashまたはdocker exec ollama ollama pull model_nameでコンテナ内を操作。
Q Docker Composeのdepends_onはサービスの準備完了を保証する?
A いいえ。depends_onは起動順序のみを保証。healthcheck + condition: service_healthyを追加して、依存サービスが本当に準備完了であることを保証すること。
Q Open WebUIとは?
A Ollamaに直接接続するオープンソースのChatGPTスタイルWebインターフェース。非技術ユーザーやデモ用途に適している。1コマンドDockerデプロイ。
Q 複数コンテナでGPUを共有するには?
A --gpus allで全コンテナがGPUを共有。Ollamaは内部でリクエストをキューイング。分離する場合は--gpus '"device=0"'--gpus '"device=1"'で異なるGPUを割り当て。

📖 まとめ


📝 練習問題

  1. 基本(難易度 ⭐):DockerでOllamaコンテナを実行し、モデルをプルし、API経由で対話をテストする。
  2. 中級(難易度 ⭐⭐):Docker Compose設定を記述してOllama + Open WebUIを起動し、WebUIで対話を完了する。
  3. 上級(難易度 ⭐⭐⭐):完全なSupportBotフルスタック(Ollama + FastAPI + Chroma + WebUI)をデプロイし、RAG Q&Aを実装し、永続性を検証する。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%