趋近智
docker run 运行训练任务docker-compose.yml中定义服务在部署机器学习模型进行推理时,Docker 镜像的大小是一个重要因素。较大的镜像下载时间更长,占用存储空间更多,并且可能通过包含不必要的构建工具或库来增加受攻击面。导致镜像过大的一个常见原因是包含了构建时依赖,例如编译器、头文件,甚至整个 SDK,这些是安装库所需的,但在运行最终应用时却不需要。
多阶段构建为此问题提供了一个有效办法。它们允许您在一个 Dockerfile 中使用多个 FROM 指令。每个 FROM 指令都可以使用不同的基础镜像,并开始一个新的构建“阶段”。您可以选择性地将产物(例如编译后的代码、已安装的依赖或模型文件)从一个阶段复制到另一个阶段,而将最终镜像中不需要的一切留下。
这种做法包括为构建和运行应用设定不同的阶段:
AS <stage_name>(例如 AS builder)来给这个阶段命名。python:3.9-slim 或一个 distroless 镜像)。它只包含运行您的推理服务所必需的组件。COPY --from=<stage_name> 指令。此命令将指定的前一阶段(例如 builder)中的特定文件或目录复制到最终阶段的文件系统中。这个过程确保最终镜像只包含运行时应用、其直接依赖项以及任何需要的数据文件,同时舍弃中间构建环境及其附带的冗余。
考虑一个使用 FastAPI 构建的推理服务,它需要可能带有复杂构建依赖的库。一个多阶段 Dockerfile 可能像这样:
# 阶段 1: 构建器阶段,包含构建工具
FROM python:3.9 AS builder
WORKDIR /app
# 如有需要,安装构建必备工具(Debian系镜像示例)
# RUN apt-get update && apt-get install -y --no-install-recommends build-essential
# 先只复制 requirements 文件,以利用 Docker 缓存
COPY requirements.txt .
# 安装所有依赖,包括构建时依赖
# 在构建阶段使用虚拟环境有助于隔离软件包
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码的其余部分
COPY . .
# 可选:如果模型文件没有随代码复制,则在此处下载
# RUN python download_model.py
# 阶段 2: 最终阶段,使用精简运行时环境
FROM python:3.9-slim
WORKDIR /app
# 从构建器阶段复制虚拟环境
COPY --from=builder /opt/venv /opt/venv
# 复制应用代码(如有需要请调整路径)
COPY --from=builder /app /app
# 如果模型文件在构建器阶段已下载或属于应用代码的一部分,则在此处复制
# COPY --from=builder /app/models /app/models
# 使端口 80 在容器外部可用
EXPOSE 80
# 定义环境变量
ENV NAME
# 设置路径以包含虚拟环境的二进制文件
ENV PATH="/opt/venv/bin:$PATH"
# 运行应用
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
在此示例中:
builder 阶段使用标准 python:3.9 镜像,将 requirements.txt 中的依赖安装到虚拟环境 (/opt/venv) 中,并复制应用代码。python:3.9-slim 镜像开始。COPY --from=builder /opt/venv /opt/venv 将包含所有已安装 Python 软件包的整个虚拟环境从构建器阶段复制到最终阶段。COPY --from=builder /app /app 复制应用源代码。builder 阶段的中间层。此图示说明了在多阶段 Docker 构建中,如何将特定产物(虚拟环境、应用代码)从较大的构建阶段复制到较小的最终运行时阶段。
COPY --from 正确复制它们。这可能包含已安装的软件包(例如 site-packages 目录或虚拟环境)、编译后的二进制文件、静态资源和模型文件。检查中间构建阶段容器的文件系统(docker run --rm -it <builder_image_id> bash)会很有帮助。slim、alpine 或 distroless)。多阶段构建是创建生产可用容器镜像的标准做法,对于效率和安全性是重要考量的机器学习推理服务来说尤其适用。通过将构建时需求与运行时必要项分离,您可以创建更精简、更快速、更安全的容器来服务您的模型。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造