乱谈府

乱谈府

Docker环境开发部署流程

6
2025-08-23
Docker环境开发部署流程

之前一直在 windows 环境中编写基于 python 算法和后端,初期开发的时候没遇到啥问题。但随着后面部署和环境兼容性的需求的出现,windows 环境中各种依赖的复杂项和一些本身系统的缺陷让我产生了迁移开发环境的想法。虽然 windows 上面的 wsl 用起来也不赖,不过考虑到终究是要使用 docker 部署的,为何不直接在 docker 环境中开发,还可以测试环境的独立性。
本文是自己在使用 docker 进行开发环境和部署环境构建的一些经验总结,可能有不对的地方,仅作记录和抛砖引玉。

环境需求

虽然我最开始是做算法相关的,但是手头的项目慢慢变成了一个基于 python 做后端的复杂项目。其中包含数据库的构建,各种方法 API 的调用,异步任务,在线读图功能,深度学习模型推断功能等等。前三点都可以找到比较合适的 python 库中的框架,例如我选择的是 Flask + Flask-SQLAlchemy + Celery 组合,本质上只要安装对应的包即可。但后面两点对环境的要求极高,首先是在线读图功能,它需要兼容多种不同的切片格式的读取分析,而这其中不同的格式会依赖于不同底层的 C++封装的库,进而导致 windows 和 linux 环境依赖不同。深度学习模型推断更不用说,pytorch 对不同架构不同 cuda 版本都有严格的限制。结合平台间路径读取的不一致,选用 docker 将环境统一再开发是一件省时省力的事。

Windows 安装 docker 这件事就不赘述了,主要是安装 docker-desktop,wsl 2 和 wsl 环境(如 Ubuntu 22.04 LTS)。并在 docker-desktop 设置中 Resources-WSL integration 中打开对应的环境。

开发环境

整体分为构建镜像和开发环境启动两部分。

构建镜像

由于需要适配 gpu,所以开发环境选择有 cudnn 环境的镜像,这里基础镜像选择 12.6.3-cudnn-runtime-ubuntu22.04,开发阶段构建的镜像仅包含基础的软件环境,用于开发调试。这里我将 torch 相关的依赖都下载到了本地 dependence/torch 文件夹下,采取分阶段构建的方式,不然会在镜像中留存复制操作的所有文件,导致镜像增大。示例代码 Dockerfile-dev 如下

# 阶段1:构建和安装依赖 无copy层 减少镜像大小
FROM nvidia/cuda:12.6.3-cudnn-runtime-ubuntu22.04 AS builder

ENV DEBIAN_FRONTEND=noninteractive

# 安装构建所需的依赖(与最终镜像保持一致很重要)
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    libopenslide-dev \
    libgl1-mesa-glx \
    libglib2.0-0 \
    python3.10 \
    python3.10-dev \
    python3-pip \
    git \
    libnuma1 \
    tzdata \
    && rm -rf /var/lib/apt/lists/*

# 设置 Python 别名
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 && \
    update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1

# 升级 pip
RUN python -m pip install --upgrade pip

# 安装所有 torch 相关的包
COPY dependence/torch/*.whl /tmp/wheels/
RUN pip install --no-cache-dir /tmp/wheels/*.whl && \
    pip cache purge

# 验证安装
RUN pip list | grep torch

# 阶段2:最终镜像
FROM nvidia/cuda:12.6.3-cudnn-runtime-ubuntu22.04

ENV TZ=Asia/Shanghai
ENV DEBIAN_FRONTEND=noninteractive

# 安装运行时依赖(必须与 builder 保持一致)
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    libopenslide-dev \
    libgl1-mesa-glx \
    libglib2.0-0 \
    python3.10 \
    python3.10-dev \
    python3-pip \
    git \
    libnuma1 \
    tzdata \
    && rm -rf /var/lib/apt/lists/*

# 配置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 设置 Python 别名
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 && \
    update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1

# 升级 pip 到相同版本
RUN python -m pip install --upgrade pip

# 完整复制 Python 环境
COPY --from=builder /usr/local/lib/python3.10 /usr/local/lib/python3.10
COPY --from=builder /usr/local/bin /usr/local/bin

# 验证 torch 是否正确复制
#RUN pip list | grep torch && \
#    python -c "import torch; print('PyTorch version:', torch.__version__); print('CUDA available:', torch.cuda.is_available())"

WORKDIR /app

# 安装其他依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple && \
    pip cache purge

使用命令进行构建

docker build -f Dockerfile-dev -t docker-dev:1.0 .

之后可以在 docker desktop 中看到构建的镜像文件。

环境启动

启动开发时,直接使用 docker compose 配置文件启动,示例代码 docker-compose-dev.yml 如下

version: '3.8'

services:
  # 服务名可以任意,比如 app, dev, my_env...
  app:
    image: docker-dev:1.0
    container_name: docker-dev

    ports:
      - "8098:8098"

    # 启用GPU!这套新的标准语法可以确保容器能访问到GPU资源
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ['0'] # 明确指定ID为0的GPU
              capabilities: [gpu]

    # 共享内存,用于控制pytorch推断过程中workers的内存大小,仅workers>0需调整
    shm_size: '4gb'

    # 环境变量配置
    environment:
      # --- 数据库配置 ---
      - DATABASE_URL=xxxx
  
  

      # C依赖库
      - LD_LIBRARY_PATH=/app/dependence/xx

      # huggingface配置
      - HF_HOME=/app/dependence/hf_cache


    # 项目文件夹映射
    volumes:
      - .:/app

    # 启动主应用
    command: python app.py

使用命令启动:

## 启动特定的docker-compose文件
docker compose -f docker-compose-dev.yml up -d

## 停止服务
docker compose -f docker-compose-dev.yml stop

## 删除服务
docker compose -f docker-compose-dev.yml down

如果你使用 pycharm 作为 ide,可以在 Services 选项栏中看到对应 docker 的镜像和正在运行容器,查看对应 log 并对程序进行运行调试等操作。开发流程基本和 windows 原生开发差不多,就是每次程序启动可能稍慢,体验还是不错的。

部署环境

部署环境基本就是开发环境的延续,本质上就是将项目文件夹中必要的东西也打包进去。不过因为有了开发环境,可以在这个基础上直接进行打包。打包示例代码 Dockerfile-prob 如下:

# 使用开发环境构建的 torch 基础镜像
FROM wsi-docker-dev:1.0 AS base

WORKDIR /app

# 复制应用代码(这里会用到 .dockerignore排除特定文件)
COPY . .

# 声明应用将要监听的端口
EXPOSE 8098

构建后进行启动,对应的 docker-compose-prob.yml 和开发环境基本一致,注意修改挂载的数据即可。

当然,部署环境应该还要做更多的改动,例如加密和一些部署的专业性调整,后续变化了继续补充。