You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多阶段构建为何让我的Python Docker镜像体积变大?

多阶段构建Docker镜像体积反而增大的原因解析

问题场景

常规单阶段构建的Docker镜像体积为216MB,但采用下述多阶段构建方案后,最终镜像体积达到227MB,为何会出现这种反效果?

多阶段构建Dockerfile

# This multi stage build Dockerfile actually makes the image larger! :(
FROM python:3.10.14-slim-bookworm AS base

LABEL authors="X"

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV ENVIRONMENT=production
ENV PYTHONPATH=/app

WORKDIR /app

FROM base AS build

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt && \
    rm requirements.txt

FROM base AS final

# cleaning up unused files
RUN  rm -rf /var/lib/apt/lists/*

COPY --from=build /usr/local/lib/python3.10/site-packages/ /usr/local/lib/python3.10/site-packages/


COPY ./src /app/src
# Expose port 8000 for FastAPI server
EXPOSE 8000

ENTRYPOINT ["python", "/app/src/main.py"]

依赖清单requirements.txt

fastapi==0.111.0
loguru==0.7.2
aiohttp[speedups]==3.9.5
boto3==1.34.128

核心原因分析

  • 镜像层操作冗余:单阶段构建时,pip install和rm -rf /var/lib/apt/lists/*在同一镜像层完成,修改操作直接覆盖原有层内容,空间利用率更高。而多阶段的final阶段基于base镜像单独执行清理,虽减少部分体积,但后续复制site-packages新增的独立层增量,超过了清理带来的收益。
  • 目录复制的层增量:多阶段构建复制整个site-packages目录会生成全新镜像层,而单阶段构建中pip install直接在基础镜像层写入依赖,不会额外新增完整的依赖目录层。Docker分层存储机制下,新增复制层会包含所有依赖文件的完整数据,单阶段的修改则是原有层的增量更新,空间占用更少。
  • 基础镜像内容重复存储:base镜像本身已包含site-packages的基础内容,多阶段复制时会将build阶段新增依赖与基础内容合并到新层;单阶段构建直接在原有site-packages层添加依赖,避免了基础文件的重复存储冗余。
  • 无构建依赖可剥离:多阶段构建的核心优势是剥离构建工具(如编译器、构建依赖包),但这里使用的python:slim-bookworm已是轻量镜像,无多余构建工具,因此无法通过剥离构建依赖缩减体积,反而因分层操作增加额外开销。

优化方案

  • 提前在base镜像中执行rm -rf /var/lib/apt/lists/*,避免final阶段重复操作,减少不必要的镜像层。
  • 使用pip install --target=/tmp/deps指定依赖安装目录,再复制该目录到final阶段的site-packages,仅复制新增依赖文件,避免覆盖或重复存储基础内容。
  • 执行docker history <镜像ID>查看各层体积变化,精准定位增量来源,针对性调整构建步骤。

内容的提问来源于stack exchange,提问作者CyberPlayerOne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:22:14