使用 Docker Compose 实现灵活部署与管理 Ollama

1,735 阅读12分钟

Ollama 作为一款流行的本地大语言模型运行框架,其官方安装方式简洁高效。然而,对于追求更高灵活性、跨平台一致性以及希望简化管理流程的用户而言,采用 Docker Compose 来部署 Ollama 提供了一种颇具吸引力的替代方案。下面我将详细介绍我是如何利用 Docker Compose 在 Windows (WSL2)、Linux 及 macOS 上部署和管理 Ollama,并探讨这种方法的实际优势。

为何选择 Docker Compose 部署 Ollama?

虽然原生安装直接方便,但在某些场景下可能遇到一些挑战:

  1. 环境隔离问题:原生安装可能与本地其他开发工具或库产生依赖冲突。
  2. 迁移与备份复杂度:更换设备或重装系统时,迁移 Ollama 的模型数据和配置相对繁琐。
  3. 跨平台差异:不同操作系统下的安装细节和管理方式可能存在细微差别。
  4. 更新流程:手动检查和执行更新步骤可能不够流畅。
  5. 资源精细化控制:例如,精确分配 GPU 资源可能需要额外的配置步骤。

引入 Docker Compose,我们可以将 Ollama 及其运行环境打包成一个独立的、容器化的服务单元,从而获得显著优势:

  • 出色的环境隔离:Docker 容器提供了一个干净、隔离的运行环境,有效避免了依赖冲突。
  • 跨平台一致性:一份 docker-compose.yml 配置文件即可在所有支持 Docker 的平台上实现相同的部署和运行效果。
  • 便捷的迁移与备份:只需备份和迁移包含配置文件和数据的 ~/.ollama 目录,即可在新环境中快速恢复 Ollama 服务及其所有模型。
  • 简化的更新管理:通过预设的脚本,可以轻松实现拉取最新 Ollama 镜像并重新部署服务。
  • 集中化配置管理:所有关键配置,如端口映射、数据卷挂载、环境变量以及资源限制(如 GPU),都集中定义在 docker-compose.yml 文件中,清晰明了。
  • 后台稳定运行:利用 Docker 的容器管理机制,可以确保 Ollama 服务在后台稳定运行。
  • 灵活的网络配置:方便地配置如 OLLAMA_ORIGINS 等参数,以控制 API 的访问权限。

部署步骤

准备工作:请确保你的系统已安装 Docker 和 Docker Compose。如果尚未安装,请参考官方文档进行安装。

第一步:创建配置与数据目录

首先,在用户主目录下创建一个专门用于存放 Ollama 相关文件的目录:

mkdir ~/.ollama
cd ~/.ollama

接下来,在此目录中创建两个核心文件:docker-compose.ymlupdate-ollama.sh (更新容器的脚本)。

第二步:编写 docker-compose.yml 文件

创建 docker-compose.yml 文件,并填入以下内容,用于定义 Ollama 服务:

services:
  ollama:
    # 使用官方最新镜像
    image: ollama/ollama:latest
    # 定义容器名称,方便管理
    container_name: ollama
    # 设置重启策略:除非手动停止,否则容器将在退出后自动重启
    restart: unless-stopped
    environment:
      # 配置允许访问 Ollama API 的来源地址。'*' 表示允许所有来源。
      # 注意:安全性自己保障,我这里是为了LobeChat 使用方便
      - OLLAMA_ORIGINS=*
    ports:
      # 将宿主机的 11434 端口映射到容器内的 11434 端口
      - "11434:11434"
    volumes:
      # 将宿主机的 ~/.ollama/data 目录挂载到容器内的 /root/.ollama 目录
      # 这是 Ollama 存储模型文件和元数据的地方,实现数据的持久化存储。
      - ~/.ollama/data:/root/.ollama
    deploy:
      # --- 资源部署配置段 ---
      resources:
        reservations:
          # GPU 资源预留配置 (仅当需要并配置了 NVIDIA GPU 时启用)
          devices:
            # 指定使用 nvidia 驱动
            - driver: nvidia
              # 使用所有检测到的 NVIDIA GPU
              count: all
              # 请求 GPU 相关能力
              capabilities: [gpu]
      # --- GPU 配置段结束 ---

配置解读

  • image: 指定使用官方 ollama/ollama:latest 镜像。
  • container_name: 将容器命名为 ollama,便于后续通过名称进行操作。
  • restart: unless-stopped: 确保容器具有较好的自恢复能力。
  • environment: OLLAMA_ORIGINS=* 设置允许所有来源访问 API,便于本地开发和测试。
  • ports: 将宿主机的 11434 端口暴露出来,映射到容器的同名端口,使得可以通过 http://<宿主机IP>:11434 访问 Ollama API。
  • volumes: 这是实现数据持久化和便捷迁移的关键。将宿主机的 ~/.ollama/data 目录映射到容器内 Ollama 的工作目录。所有下载的模型和相关数据都将保存在宿主机上,即使容器被删除重建,数据依然保留。迁移时只需复制 ~/.ollama 目录。
  • deploy.resources.reservations.devices: 特别说明:此部分用于配置 NVIDIA GPU 加速。如果你使用的是 Apple Silicon (M系列芯片) 的 Mac,Docker Desktop for Mac 通常会自动利用 Metal 实现 GPU 加速,一般不需要此 deploy 配置,可以将其整个移除。对于其他平台,如果你没有 NVIDIA GPU 或不打算使用 GPU 加速,也应移除此 deploy 部分。若要启用 NVIDIA GPU 支持,请确保已正确安装 NVIDIA Container Toolkit 并配置 Docker。

第三步:创建 update-ollama.sh 更新脚本

为了方便地将 Ollama 更新到最新版本,我们创建一个更新脚本 update-ollama.sh

#!/bin/bash

# 自动更新 Ollama Docker 服务的脚本
# 创建日期: $(date)

# 设置脚本在遇到错误时立即退出
set -e

# 定义日志文件路径 (确保目录存在)
LOG_FILE="$HOME/.ollama/update.log"
mkdir -p "$(dirname "$LOG_FILE")" # 如果目录不存在,则创建

# 日志记录函数,同时输出到控制台和日志文件
log() {
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    echo "[$timestamp] $1" | tee -a "$LOG_FILE"
}

# 错误处理函数
handle_error() {
    log "错误:脚本在第 $1 行执行失败。"
    log "Ollama 更新过程意外中止。"
    exit 1
}

# 设置错误捕获
trap 'handle_error $LINENO' ERR

# 开始更新流程
log "启动 Ollama 更新程序..."

# 切换到包含 docker-compose.yml 的目录
cd "$HOME/.ollama" || { log "错误:无法切换到目录 $HOME/.ollama"; exit 1; }

# 拉取最新的 ollama/ollama 镜像
log "正在拉取最新的 Ollama 镜像: ollama/ollama:latest..."
if ! docker pull ollama/ollama:latest; then
    log "错误:拉取最新镜像失败。请检查网络连接或 Docker Hub 状态。"
    exit 1
fi
log "成功拉取最新镜像。"

# 优雅地停止当前运行的服务
log "正在停止当前的 Ollama 服务 (容器: ollama)..."
# 设置超时时间,并移除孤立的容器(如果存在)
if ! docker-compose down --timeout 120 --remove-orphans; then
    log "警告:'docker-compose down' 执行时遇到问题,但将继续尝试。"
    # 作为备用方案,尝试直接停止和移除容器
    if docker ps -a --format '{{.Names}}' | grep -q "^ollama$"; then
        log "尝试直接停止并移除 'ollama' 容器..."
        docker stop ollama || log "警告:停止 'ollama' 容器失败。"
        docker rm ollama || log "警告:移除 'ollama' 容器失败。"
    fi
fi
log "旧的 Ollama 服务已停止。"

# 使用新的镜像启动服务
log "正在使用最新镜像启动 Ollama 服务 (docker-compose up -d)..."
if ! docker-compose up -d; then
    log "错误:启动 Ollama 服务失败 ('docker-compose up -d')。请检查 Docker Compose 配置和 Docker 状态。"
    exit 1
fi

# 验证服务是否成功启动
log "正在验证 Ollama 服务状态..."
# 等待几秒钟让容器充分启动
sleep 5
if docker-compose ps | grep -q "ollama.*(Up|running)" ; then # 检查状态是否为 Up 或 running
    log "成功!Ollama 服务已使用最新镜像启动并运行。"
else
    log "错误:更新后 Ollama 服务未能正常启动。请检查容器日志:'docker logs ollama'"
    # 输出容器日志以帮助诊断
    docker logs ollama || true
    exit 1
fi

# 清理不再使用的旧 Docker 镜像 (可选但推荐)
log "正在清理未使用的 Docker 镜像..."
docker image prune -f
log "镜像清理完成。"

log "Ollama 更新过程顺利完成。"

# 尝试获取并输出当前运行的 Ollama 版本
log "正在尝试获取当前 Ollama 版本..."
CURRENT_VERSION=$(docker exec ollama ollama --version 2>/dev/null || echo "无法确定版本")
log "当前 Ollama 版本: $CURRENT_VERSION"

exit 0

脚本功能说明

  • 该脚本自动化了更新流程:切换到工作目录 -> 拉取最新镜像 -> 停止旧容器 -> 启动新容器 -> 清理旧镜像 -> 记录日志并报告版本。
  • 请赋予此脚本执行权限:chmod +x ~/.ollama/update-ollama.sh
  • 之后,只需运行 ~/.ollama/update-ollama.sh 即可执行更新操作。

第四步:启动 Ollama 服务

~/.ollama 目录下,执行以下命令首次启动 Ollama 服务:

docker-compose up -d

参数 -d 表示在后台(detached mode)运行。Docker 将根据 docker-compose.yml 文件下载所需镜像(如果本地不存在),然后创建并启动 ollama 容器。

你可以使用 docker ps 命令查看容器是否正在运行,或使用 docker logs ollama 命令查看服务的实时日志。

提升体验:配置 Shell 别名

至此,Ollama 服务已在 Docker 容器中成功运行。但每次与 Ollama 命令行交互都需要输入类似 docker exec ollama ollama <command> 的命令,这显然不够便捷。为了获得接近原生安装的使用体验,我们可以配置两个 Shell 别名。

编辑你的 Shell 配置文件(常见的有 ~/.zshrc 对于 Zsh,或 ~/.bashrc 对于 Bash),在文件末尾添加以下内容:

# Ollama Docker 容器快捷命令别名
alias ollama='docker exec ollama ollama'
alias ollama-shell='docker exec -it ollama /bin/sh'

别名解释

  • alias ollama='docker exec ollama ollama': 这个别名将 ollama 命令映射为在名为 ollama 的 Docker 容器内部执行 ollama 程序。配置生效后,你就可以在宿主机终端直接使用标准的 Ollama 命令,如 ollama pull <model>, ollama run <model>, ollama list 等,操作方式与原生安装无异。
  • alias ollama-shell='docker exec -it ollama /bin/sh': 这个别名提供了一个快捷方式,用于启动一个连接到 ollama 容器内部的交互式 Shell (/bin/sh)。这对于需要直接在容器环境中进行调试或执行特定命令的场景非常有用。

添加别名后,需要重新加载 Shell 配置使其生效:

# 如果你使用 Zsh
source ~/.zshrc

# 如果你使用 Bash
source ~/.bashrc

现在,你可以像使用原生安装一样与 Ollama 交互了:

# 查看 Ollama 版本
ollama --version
ollama version is 0.6.7

# 拉取一个模型
ollama pull qwen3:30b-a3b
pulling manifest 
pulling e9183b5c18a0: 100% ▕██████████████████▏  18 GB                         
pulling eb4402837c78: 100% ▕██████████████████▏ 1.5 KB                         
pulling d18a5cc71b84: 100% ▕██████████████████▏  11 KB                         
pulling cff3f395ef37: 100% ▕██████████████████▏  120 B                         
pulling d4b865b4a92d: 100% ▕██████████████████▏  494 B                         
verifying sha256 digest 
writing manifest 
success 

# 使用模型进行交互
ollama run qwen3:30b-a3b "介绍一下你自己"
<think>
好的,用户让我介绍一下自己。首先,我需要明确自己的身份和功能。我是一个大型语言模型,由阿里云开发的Qwen。我需要简洁明了地说明我的基本属性,比如我是谁,能做什么。

接下来,我应该涵盖我的主要功能,比如回答问题、创作文字、逻辑推理、编程等。同时,要提到我支持多种语言,这样用户知道我可以处理不同语言的请求。

然后,我需要强调我的应用场景,比如学习、工作、生活中的帮助,这样用户能理解我在不同情境下的用途。还要提到我的持续学习和优化,说明我能够不断进步,提供更好的服务。

另外,要确保语气友好,鼓励用户提出具体问题,这样能促进互动。同时,避免使用过于技术化的术语,保持口语化,让用户容易理解。

可能还需要检查是否有遗漏的重要信息,比如我的训练数据截止日期,或者是否有任何限制。不过根据之前的指示,可能不需要提到这些细节,除非用户特别问到。

最后,确保回答结构清晰,分点或分段,但不要使用Markdown格式。保持自然流畅的中文表达,让用户感到亲切和专业。
</think>

你好!我是通义千问,是阿里巴巴集团旗下的通义实验室自主研发的超大规模语言模型。我可以回答问题、创作文字、逻辑推理、编程等,支持多种语言,包括中文、英文、法语、西班牙语、葡萄牙语、俄语、德语、日语、韩语、泰语、越南语、印尼语等。

我的训练数据涵盖了大量文本,包括书籍、文章、代码等,这让我能够理解和生成各种类型的文本内容。我被设计用来帮助用户获取信息、解决问题和创造新内容。

如果你有任何问题或需要帮助,随时告诉我!我会尽力提供帮助。

# 列出本地已下载的模型
ollama list
NAME               ID              SIZE      MODIFIED     
mistral:latest     f974a74358d6    4.1 GB    41 hours ago    
qwen3:30b-a3b      2ee832bc15b5    18 GB     42 hours ago    
qwen3:30b          2ee832bc15b5    18 GB     45 hours ago    
qwen3:32b          e1c9f234c6eb    20 GB     47 hours ago    
qwen3:14b          7d7da67570e2    9.3 GB    2 days ago      
qwen3:8b           e4b5fd7f8af0    5.2 GB    2 days ago      
gemma3:27b         30ddded7fba6    17 GB     7 weeks ago     
qwen2.5:7b         845dbda0ea48    4.7 GB    2 months ago    
deepseek-r1:32b    38056bbcbb2d    19 GB     2 months ago    
deepseek-r1:14b    ea35dfe18182    9.0 GB    2 months ago    
deepseek-r1:7b     0a8c26691023    4.7 GB    2 months ago    
qwen2.5:14b        7cdf5a0187d5    9.0 GB    4 months ago    
gemma2:9b          ff02c3702f32    5.4 GB    4 months ago    
gemma:7b           a72c7f4d0a15    5.0 GB    4 months ago    
llama3.1:8b        46e0c10c039e    4.9 GB    4 months ago    
llama3.2:3b        a80c4f17acd5    2.0 GB    4 months ago   

# 进入容器的 Shell 环境 (输入 exit 或按 Ctrl+D 退出)
ollama-shell
# 在容器内执行命令,例如查看模型目录内容
ls /root/.ollama/models
exit

WSL2 启动时机问题

如果使用的是windows那一般docker其实是装在windows的,这时候如果wsl2的docker需要挂载一个目录的时候会和wsl2本身的启动时机有时间上的先后冲突,导致目录挂载失败,但是容器已经启动了,目前我也没有太好的解决办法,只能在用之前用list查看一下,如果是空的就把容器重启一下即可。

总结

通过 Docker Compose 部署 Ollama,我们构建了一个具有良好跨平台兼容性、易于迁移备份、更新流程简化、配置集中管理的本地大模型运行环境。结合简单的 Shell 别名配置,还能获得几乎与原生安装无差别的命令行使用体验。

这种部署方式尤其适合以下用户:

  • 需要在多个设备或操作系统上保持一致运行环境的用户。
  • 希望对 Ollama 服务进行更精细化管理,避免潜在环境冲突的开发者。
  • 看重部署灵活性和可维护性的技术爱好者。

虽然初始设置比官方一键安装略微复杂,但其在长期使用中带来的便利性、稳定性和管理上的优势,使得这种“另类”安装方法成为一个值得考虑的选择。