Docker容器化与AI大模型部署全栈指南
·
一、核心概念快速入门
1.1 Docker是什么?
Docker是一种容器化技术,可将应用及其依赖打包成轻量级、可移植的容器,实现一次构建,到处运行。
1.2 核心概念
- 镜像(Image):只读模板,包含运行应用所需的一切
- 容器(Container):镜像的运行实例
- 仓库(Registry):存储和分发镜像的地方(如Docker Hub)
二、日常操作核心命令
2.1 容器生命周期管理
创建并运行容器
# 基础格式
docker run [选项] 镜像名称 [命令]
# GPU容器示例(大模型常用)
docker run -it -v /app/xxx:/app/xxx \
--privileged \
--shm-size 100g \
--gpus all \
--name xxx_qwen2vl_evalkit \
--restart=always \
gb_qwen2vl_evalkit
关键参数详解
| 参数 | 说明 | 适用场景 |
|---|---|---|
-it |
交互式终端 | 调试、手动操作 |
-d |
后台运行 | 服务部署 |
-p HOST:CONTAINER |
端口映射 | 对外提供服务 |
-v HOST:CONTAINER |
数据卷挂载 | 数据持久化 |
--privileged |
特权模式 | 需要高级权限(慎用) |
--shm-size |
共享内存大小 | PyTorch等需要大内存 |
--gpus all |
使用所有GPU | AI模型训练/推理 |
--name |
容器命名 | 便于管理 |
--restart=always |
自动重启 | 生产环境服务 |
2.2 容器日常操作
# 查看容器
docker ps # 运行中的容器
docker ps -a # 所有容器(含已停止)
# 启动/停止/重启
docker start <容器名/ID>
docker stop <容器名/ID>
docker restart <容器名/ID>
# 进入容器(后台运行时)
docker exec -it <容器名/ID> /bin/bash
# 删除容器
docker rm <容器名/ID> # 删除已停止的
docker rm -f <容器名/ID> # 强制删除运行中的
# 查看日志
docker logs <容器名/ID>
docker logs -f <容器名/ID> # 实时查看
# 资源监控
docker stats # 实时资源使用
docker top <容器名/ID> # 查看容器内进程
三、镜像管理
3.1 镜像基础操作
# 查看本地镜像
docker images
docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.Size}}"
# 拉取镜像
docker pull ubuntu:22.04
docker pull nvidia/cuda:11.8.0-base
# 删除镜像
docker rmi <镜像名:标签>
docker rmi <镜像ID>
# 镜像导出与导入
docker save -o backup.tar myimage:v1.0 # 导出
docker load -i backup.tar # 导入
3.2 从容器创建镜像
# 将容器状态保存为新镜像
docker commit -m "描述信息" <容器ID> 新镜像名:标签
# 示例
docker commit -m "添加了figlet工具" alpine-container alpine-with-figlet:latest
四、构建自定义镜像(Dockerfile)
4.1 Dockerfile核心结构
AI大模型专用Dockerfile示例
# 1. 基础镜像选择 - GPU环境
FROM nvidia/cuda:11.8.0-base-ubuntu22.04
# 2. 元数据标签
LABEL maintainer="your-team@company.com"
LABEL version="1.0"
LABEL description="Qwen2VL模型推理环境"
# 3. 环境变量优化
ENV DEBIAN_FRONTEND=noninteractive \
TZ=Asia/Shanghai \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
HF_HOME=/cache/huggingface \
HF_DATASETS_CACHE=/cache/datasets
# 4. 系统依赖安装(最小化原则)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential \
wget \
git \
curl \
ca-certificates \
python3.9 \
python3-pip \
python3.9-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 5. Conda环境安装
ENV CONDA_DIR=/opt/conda
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh && \
bash miniconda.sh -b -p $CONDA_DIR && \
rm miniconda.sh
ENV PATH=$CONDA_DIR/bin:$PATH
# 6. 复制环境配置文件并创建环境
COPY environment.yml .
RUN conda env create -f environment.yml && \
conda clean -afy
# 7. 激活环境
ENV PATH=/opt/conda/envs/llm-env/bin:$PATH
RUN echo "source activate llm-env" >> ~/.bashrc
# 8. 工作目录设置
WORKDIR /app
COPY . .
# 9. 创建非root用户(安全实践)
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
# 10. 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
# 11. 暴露端口
EXPOSE 8000
# 12. 启动命令(使用gunicorn优化)
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", \
"--bind", "0.0.0.0:8000", \
"--workers", "4", \
"--timeout", "300", \
"app:app"]
4.2 环境配置文件示例(environment.yml)
name: llm-env
channels:
- pytorch
- nvidia
- conda-forge
- defaults
dependencies:
- python=3.9.18
- cudatoolkit=11.8
- pytorch=2.2.1
- torchvision=0.17.1
- torchaudio=2.2.1
- cudnn=8.9.2.*
- pip=23.3.1
- pip:
- transformers==4.40.0
- accelerate==0.29.3
- vllm==0.4.1
- flash-attn==2.5.8
- fastapi==0.110.0
- uvicorn[standard]==0.29.0
- gunicorn==21.2.0
- huggingface-hub==0.22.2
- gradio==4.31.0
4.3 构建与优化技巧
# 基础构建
docker build -t myapp:v1.0 .
# 使用构建缓存优化
docker build --cache-from myapp:latest -t myapp:v2.0 .
# 多阶段构建(减小镜像体积)
# Dockerfile.multi
多阶段构建示例
# 第一阶段:构建阶段
FROM nvidia/cuda:11.8.0-devel-ubuntu22.04 as builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 第二阶段:运行阶段
FROM nvidia/cuda:11.8.0-base-ubuntu22.04
# 从builder复制Python包
COPY --from=builder /root/.local /root/.local
COPY --from=builder /build /app
ENV PATH=/root/.local/bin:$PATH
WORKDIR /app
CMD ["python", "app.py"]
4.4 .dockerignore文件
# 忽略不必要的文件
.git
.DS_Store
__pycache__
*.pyc
*.pyo
*.pyd
.venv
env/
venv/
.vscode/
data/
logs/
*.ipynb
README.md
test/
*.log
*.tmp
五、大模型部署专项配置
5.1 GPU环境配置
基础GPU支持
# 使用所有GPU
docker run --gpus all my-llm-app
# 指定GPU设备
docker run --gpus '"device=0,1"' my-llm-app
# 限制GPU内存
docker run --gpus all --gpus '"device=0,1"' \
--env NVIDIA_VISIBLE_DEVICES=0,1 \
my-llm-app
共享内存优化
# 大模型推理需要大共享内存
docker run --shm-size 100g --gpus all my-llm-app
# 或者使用host的/dev/shm
docker run --ipc=host --gpus all my-llm-app
5.2 数据管理策略
挂载策略建议
# ✅ 推荐:挂载必要的个人目录和数据集
docker run -it \
-v /app/xxx:/app/xxx \
-v /app/CommonDataset/datashare/:/app/CommonDataset/datashare/ \
my-llm-app
# ❌ 避免:挂载整个文件系统
docker run -it -v /gpfs:/gpfs my-llm-app # 不推荐
缓存优化
# HuggingFace缓存目录
docker run -it \
-v /path/to/hf_cache:/cache/huggingface \
-e HF_HOME=/cache/huggingface \
my-llm-app
5.3 服务化部署
单容器服务
# Gradio Web服务示例
docker run -d \
-p 8484:7810 \
-v /app/xxx:/app/xxx \
-v /app/CommonDataset/datashare/:/app/CommonDataset/datashare/ \
--privileged \
--shm-size 100g \
--gpus all \
--name xxx_gradio_qwen2vl \
--restart=always \
gb_qwen2vl_evalkit
FastAPI服务示例
# app.py
from fastapi import FastAPI
from pydantic import BaseModel
import torch
app = FastAPI(title="Qwen2VL API")
class InferenceRequest(BaseModel):
prompt: str
max_length: int = 100
@app.post("/generate")
async def generate_text(request: InferenceRequest):
# 模型推理逻辑
result = model.generate(request.prompt, max_length=request.max_length)
return {"response": result}
@app.get("/health")
async def health_check():
return {"status": "healthy"}
六、开发与调试技巧
6.1 调试容器
# 以调试模式运行
docker run -it --entrypoint=bash my-llm-app
# 连接到运行中的容器
docker exec -it <容器名> bash
# 查看容器内文件
docker cp <容器名>:/app/config.yaml ./local/
# 复制文件到容器
docker cp ./local/config.yaml <容器名>:/app/
6.2 性能监控
# 容器资源使用
docker stats <容器名>
# 容器内进程
docker top <容器名>
# GPU监控
docker exec <容器名> nvidia-smi
# 安装nvitop进行监控
docker exec -it <容器名> pip install nvitop
docker exec -it <容器名> nvitop
6.3 常见问题排查
CUDA内存不足
# 增加共享内存
docker run --shm-size 100g ...
# 检查GPU内存使用
docker exec <容器名> nvidia-smi
端口冲突
# 查看端口占用
netstat -tulpn | grep :8484
# 更换端口
docker run -p 8485:7810 ...
权限问题
# 临时解决方案(生产环境慎用)
docker run --privileged ...
# 更好的方案:在Dockerfile中配置用户
RUN useradd -m -u 1000 appuser
USER appuser
七、生产环境最佳实践
7.1 安全加固
# 使用非root用户
RUN adduser --disabled-password --gecos "" appuser
USER appuser
# 最小权限原则
# 避免使用--privileged,除非绝对必要
7.2 资源限制
# 限制CPU和内存
docker run -d \
--cpus 4 \
--memory 32g \
--gpus all \
my-llm-app
# 限制重启次数
docker run --restart=on-failure:5 my-llm-app
7.3 日志管理
# 查看日志
docker logs <容器名>
# 日志驱动配置
docker run --log-driver=json-file --log-opt max-size=100m my-llm-app
# 日志输出到文件
docker logs <容器名> > app.log 2>&1
7.4 备份与迁移
# 备份容器为镜像
docker commit <容器名> backup-image:$(date +%Y%m%d)
# 导出容器
docker export <容器名> > container.tar
# 导入容器
cat container.tar | docker import - restored-container
八、实战案例:Qwen2VL完整部署流程
8.1 环境准备
# 1. 获取基础镜像
docker pull nvidia/cuda:11.8.0-base-ubuntu22.04
# 2. 准备项目目录
mkdir -p ~/projects/qwen2vl
cd ~/projects/qwen2vl
# 3. 创建必要的目录结构
mkdir -p {config,data,logs,cache}
8.2 编写Dockerfile
# qwen2vl.Dockerfile
FROM nvidia/cuda:11.8.0-base-ubuntu22.04
# 设置时区和编码
ENV TZ=Asia/Shanghai LANG=C.UTF-8
# 安装系统依赖
RUN apt-get update && \
apt-get install -y --no-install-recommends \
python3.9 \
python3-pip \
python3.9-dev \
git \
wget \
curl \
&& rm -rf /var/lib/apt/lists/*
# 安装Python依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt \
&& pip install flash-attn --no-build-isolation
# 复制应用代码
WORKDIR /app
COPY . .
# 设置环境变量
ENV PYTHONPATH=/app
ENV HF_HOME=/app/cache/huggingface
ENV TRANSFORMERS_CACHE=/app/cache/transformers
# 暴露端口
EXPOSE 7810
# 启动命令
CMD ["python", "server.py"]
8.3 构建与运行
# 构建镜像
docker build -f qwen2vl.Dockerfile -t qwen2vl:v1.0 .
# 运行容器(开发模式)
docker run -it \
--name qwen2vl_dev \
-p 8484:7810 \
-v $(pwd)/data:/app/data \
-v $(pwd)/logs:/app/logs \
-v ~/.cache/huggingface:/app/cache/huggingface \
--shm-size 50g \
--gpus all \
qwen2vl:v1.0
# 运行容器(生产模式)
docker run -d \
--name qwen2vl_prod \
-p 8484:7810 \
-v /gpfs/qwen_data:/app/data \
-v /gpfs/qwen_logs:/app/logs \
--shm-size 100g \
--gpus all \
--restart=always \
qwen2vl:v1.0
8.4 验证服务
# 检查容器状态
docker ps | grep qwen2vl
# 查看日志
docker logs -f qwen2vl_prod
# 测试API
curl http://localhost:8484/health
curl -X POST http://localhost:8484/generate \
-H "Content-Type: application/json" \
-d '{"prompt": "你好", "max_length": 100}'
九、进阶技巧与资源
9.1 Docker Compose编排
# docker-compose.gpu.yml
version: '3.8'
services:
qwen2vl-api:
image: qwen2vl:v1.0
container_name: qwen2vl_service
ports:
- "8484:7810"
volumes:
- /gpfs/model_data:/app/models
- /gpfs/dataset:/app/dataset
- ./logs:/app/logs
environment:
- CUDA_VISIBLE_DEVICES=0,1
- HF_HOME=/app/cache/huggingface
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 2
capabilities: [gpu]
shm_size: '100g'
restart: unless-stopped
9.2 国内镜像加速
# Docker Hub镜像加速
# 在/etc/docker/daemon.json中添加
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
]
}
# 重启Docker服务
sudo systemctl restart docker
9.3 学习资源
- 官方文档:https://docs.docker.com/
- NVIDIA容器工具包:https://docs.nvidia.com/datacenter/cloud-native/
- HuggingFace容器:https://huggingface.co/docs/hub/datasets-docker
- CNB Docker训练营:https://opencamp.cn/Docker/camp/202502
十、快速参考手册
10.1 命令速查表
# 镜像管理
docker images # 列出镜像
docker pull <image> # 拉取镜像
docker build -t <name> . # 构建镜像
docker rmi <image> # 删除镜像
# 容器管理
docker run <image> # 运行容器
docker ps # 查看容器
docker exec -it <container> bash # 进入容器
docker stop <container> # 停止容器
docker rm <container> # 删除容器
# 系统管理
docker system df # 磁盘使用
docker system prune # 清理无用资源
docker login # 登录仓库
docker logout # 登出仓库
10.2 常用镜像仓库
| 仓库 | 用途 | 示例 |
|---|---|---|
| Docker Hub | 公共镜像 | ubuntu, nginx |
| NVIDIA NGC | GPU镜像 | nvidia/cuda:11.8.0 |
| HuggingFace | AI模型 | huggingface/transformers |
| CNB镜像库 | 国内加速 | docker.cnb.cool/looc/git-cnb |
10.3 故障排查清单
- 容器启动失败:检查端口占用、权限问题
- GPU不可用:确认NVIDIA驱动和容器工具包已安装
- 内存不足:增加
--shm-size,检查模型大小 - 网络问题:检查防火墙、端口映射
- 权限错误:避免使用root用户,合理配置挂载权限
更多推荐
所有评论(0)