4、Docker基础与容器化部署:Docker安装、Dockerfile编写、Docker Compose编排、镜像加速
聊到本地大模型的服务化部署,Docker 几乎是绕不开的工具。说实话,我见过不少团队在环境配置上浪费大量时间——Python 版本冲突、CUDA 驱动不匹配、依赖库打架……这些问题在 Docker 面前,基本都能迎刃而解。
这一章,我就带你从零开始,把 Docker 这套东西捋清楚。你不需要成为容器专家,但得会用、能排坑。
4.1 Docker 安装:别踩这些坑
Docker 的安装其实很简单,但不同系统有不同讲究。我个人的习惯是:能用 Linux 就别用 Windows,除非你非得在本地跑。
Linux(Ubuntu 20.04+)
# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker run hello-world
uname -r 看看内核版本,低于 4.15 的请先升级内核。
macOS / Windows
直接去 Docker Desktop 官网下载安装包就行。不过我要提醒一句:Docker Desktop 在 macOS 上默认占用 4GB 内存,如果你要跑大模型,建议手动调到 8GB 以上。
sudo 了:sudo usermod -aG docker $USER然后退出重新登录。
4.2 Dockerfile 编写:从零构建你的模型镜像
Dockerfile 说白了就是一份「菜谱」——告诉 Docker 怎么一步步把你的模型环境打包成镜像。我刚开始写 Dockerfile 时,总喜欢把所有东西塞进一层,结果镜像体积大得吓人。后来才明白:每一行 RUN 指令都会产生一个新层,层数越少越好。
一个典型的大模型推理 Dockerfile
# 基础镜像:选对 CUDA 版本很重要
FROM nvidia/cuda:12.1.0-runtime-ubuntu22.04
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
python3.10 \
python3-pip \
git \
&& rm -rf /var/lib/apt/lists/*
# 复制 requirements.txt 并安装 Python 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制模型代码
COPY . .
# 暴露服务端口
EXPOSE 8000
# 启动命令
CMD ["python3", "serve.py"]
- 基础镜像选型: 用
nvidia/cuda而非ubuntu,否则你得手动装 CUDA,麻烦得很。 - 依赖安装顺序: 先装系统依赖,再装 Python 包,最后复制代码。这样能充分利用 Docker 的缓存机制——代码改了,依赖不用重装。
- 清理缓存:
rm -rf /var/lib/apt/lists/*能减少镜像体积,我见过有人镜像 2GB,清理后只剩 800MB。
多阶段构建:瘦身利器
如果你既要编译一些 C 扩展,又不想把编译工具链带进最终镜像,多阶段构建就派上用场了。
# 第一阶段:编译
FROM python:3.10-slim as builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 第二阶段:运行
FROM python:3.10-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "serve.py"]
torch 或 tensorflow 的场景。最终镜像能小 30%-50%。
4.3 Docker Compose 编排:一键拉起整套服务
单个容器好办,但大模型服务往往需要多个组件:模型推理服务、API 网关、数据库、监控……这时候 Docker Compose 就派上用场了。说白了,它就是帮你把多个容器的启动顺序、网络、存储都编排好。
一个典型的 Compose 文件
version: '3.8'
services:
model-server:
build: ./model
ports:
- "8000:8000"
volumes:
- ./models:/app/models
environment:
- CUDA_VISIBLE_DEVICES=0
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
api-gateway:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- model-server
redis:
image: redis:7-alpine
ports:
- "6379:6379"
- GPU 资源分配: 用
deploy.resources.reservations.devices来指定 GPU,这是 Docker Compose v3.8 的新特性。老版本得用runtime: nvidia。 - 依赖顺序:
depends_on只保证启动顺序,不保证服务就绪。我建议在应用层加个健康检查。 - 数据持久化: 模型文件用
volumes挂载,这样更新模型不用重新构建镜像。
启动命令
# 后台启动
docker-compose up -d
# 查看日志
docker-compose logs -f
# 停止并删除
docker-compose down
docker-compose down 时忘了加 -v 参数,结果 Redis 的数据卷没删,下次启动时数据还在,导致模型缓存冲突。如果你要彻底清理,记得用 docker-compose down -v。
4.4 镜像加速:别让下载卡住你
国内拉 Docker 镜像,那速度……你懂的。尤其是大模型相关的镜像,动不动几个 GB,不配加速器简直没法用。
配置镜像加速器
以阿里云为例(其他云厂商类似):
# 创建或修改 /etc/docker/daemon.json
{
"registry-mirrors": ["https://your-mirror.mirror.aliyuncs.com"]
}
# 重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
手动拉取与导出
有时候镜像太大,或者网络实在不行,我建议你换个思路:
- 找一台网络好的机器(比如海外 VPS)拉取镜像
- 用
docker save导出为 tar 文件 - 传到目标机器,用
docker load导入
# 导出
docker save nvidia/cuda:12.1.0-runtime-ubuntu22.04 -o cuda.tar
# 导入
docker load -i cuda.tar
nvidia/cuda 这种官方镜像,加速器可能也救不了——因为官方镜像通常不在加速器缓存里。这时候,手动导出导入反而是最靠谱的。
知识体系总览
下面这张图,帮你把本章的核心逻辑串起来:
嗯,到这里 Docker 的基础和容器化部署就讲完了。你可能会觉得内容有点多,但别急——这些东西你只要动手做一遍,就全记住了。我当年也是踩了不少坑才总结出这些经验,希望你能少走弯路。