Ollama: Docker容器化部署

Docker 让 Ollama 变成乐高积木——拉取镜像、编排组合、一键部署。

⚠️ 注意:Docker 容器默认不持久化数据——容器删除后模型文件全部丢失(动辄数 GB)。必须使用 Volume 挂载(-v ollama_data:/root/.ollama)将模型数据持久化到宿主机,生产环境绝不可省略。

📋 前置知识:需要先掌握以下内容

1. 你将学到


2. 一个 SaaS 创业者的真实故事

(1) 痛点:每台服务器都要手动装 Ollama

Alice 的 SupportBot 要部署到 3 台服务器,每台手动安装 Ollama、拉取模型、配置环境。版本不一致、配置遗漏、环境差异导致各种问题。

(2) 解法: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 only 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 image] --> B{GPU available?}
    B -->|NVIDIA| C[nvidia-container-toolkit<br/>--gpus all]
    B -->|AMD| D[rocm image<br/>--device /dev/kfd]
    B -->|None| E[CPU-only mode]
    C --> F[Ollama Server :11434]
    D --> F
    E --> F

▶ 示例 1: 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

▶ 示例 2: 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...

▶ 示例 3: 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 可一键编排多个服务(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 Reverse Proxy] --> B[FastAPI App<br/>:8000]
    B --> C[Ollama<br/>:11434]
    B --> D[Chroma DB<br/>:8001 Vector Store]
    C --> E[Model Volume]
    D --> F[Chroma Volume]

(2) docker-compose.yml 模板

服务 镜像 端口 依赖
ollama ollama/ollama 11434 GPU runtime
webui open-webui/open-webui 3000 ollama
chroma chromadb/chroma 8000
app custom fastapi 8001 ollama, chroma

▶ 示例 4: 完整 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 挂载对比

方式 命令 持久化 性能
Named Volume -v ollama_data:/root/.ollama ✅ Docker 管理
Bind Mount -v /data/ollama:/root/.ollama ✅ 宿主机管理 最好
tmpfs --tmpfs /root/.ollama ❌ 内存 最快

(2) 网络模式对比

模式 命令 适用 说明
bridge 默认 容器间通信 需端口映射
host --network host 低延迟 共享宿主机网络
自定义网络 docker network create mynet 多服务 DNS 自动解析

▶ 示例 5: 生产级 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 📖 仅展示
# 验证配置文件语法
docker compose config --quiet && echo "✅ 配置文件语法正确"
# 输出:✅ 配置文件语法正确

7. 综合示例:SupportBot 全栈 Docker 部署

ℹ️ 信息: init-models 容器是一个"一次性任务"模式——它在 Ollama 健康检查通过后自动拉取所需模型,完成后退出。这样无需手动进入容器执行 ollama pull,实现真正的"一键部署"。

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) 是否生效;2) nvidia-container-toolkit 是否安装;3) Docker runtime 是否配置为 nvidia。
Q 容器重启后模型还在吗?
A 如果在 挂载了 Volume,模型数据持久化保留。没有 Volume 则丢失,需重新拉取。
Q 如何进入容器执行 ollama 命令?
A 或 进入容器后操作。
Q Docker Compose 的 depends_on 能保证服务就绪吗?
A 不能。depends_on 只保证启动顺序。加 healthcheck + condition: service_healthy 可确保依赖服务真正就绪。
Q Open WebUI 是什么?
A 开源的 ChatGPT 风格 Web 界面,直接连接 Ollama。适合非技术用户使用,也适合演示。Docker 一键部署。
Q 多容器如何共享 GPU?
A 使用 让所有容器共享 GPU。Ollama 内部会排队处理请求。如需隔离,用 和 分配不同 GPU。

📖 小节


📝 作业

  1. 基础题(难度⭐):用 Docker 运行 Ollama 容器,拉取一个模型,通过 API 测试对话。
  2. 进阶题(难度⭐⭐):编写 Docker Compose 配置,启动 Ollama + Open WebUI 两个服务,在 WebUI 中完成对话。
  3. 挑战题(难度⭐⭐⭐):部署完整 SupportBot 全栈(Ollama + FastAPI + Chroma + WebUI),实现 RAG 问答并验证持久化。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏