返回首页

Python Docker 优化:-43-57% 大小

文章剖析 Python Docker 镜像优化:多阶段构建减少 43% 大小,scratch 减少 57%。Dockerfile 示例、基准测试、dive 分析。适合中高级开发者。

Python Docker:使用 scratch 和多阶段 大小 -57%
Advertisement 728x90

优化 Python Docker 镜像:体积缩减 43–57%

多阶段构建和 Python 精简镜像可将运行时镜像体积从 895 MB 降至 508 MB(-43%)。代码变更后的构建时间从 56 秒缩短至 16 秒。这加速了 Kubernetes 部署,节省了存储空间并减少了流量。

优化解决了关键问题:流量高峰时的快速 Pod 扩展和降低用户延迟。依赖项通过 Poetry 管理,测试在构建阶段运行。

.dockerignore 与精简镜像

通过 .dockerignore 排除测试和不必要的文件。测试仅在构建阶段需要。

Google AdInline article slot

切换到 python:3.13-slim-bookworm。完整镜像会增加数百 MB。

使用标志禁用 pip/Poetry 缓存:

  • pip:--no-cache-dir
  • Poetry:poetry cache clear --all pypi

多阶段构建:Dockerfile 详解

构建阶段安装 Poetry、依赖项并运行 pytest。运行时阶段仅复制 site-packages、二进制文件(gunicorn、uvicorn)和代码。

Google AdInline article slot
# 构建阶段
FROM python:3.13-slim-bookworm AS builder
ENV PYTHONUNBUFFERED=1 \
    LANG=C.UTF-8 \
    PYTHONDONTWRITEBYTECODE=1

RUN apt-get update -qq && \
    apt-get install -y --no-install-recommends \
      curl \
      gcc \
      libc-dev \
    && pip install --no-cache-dir 'poetry==2.3.2' \
    && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /code

COPY pyproject.toml poetry.lock* ./

RUN poetry config virtualenvs.create false \
  && poetry install --no-root --no-dev --no-interaction --no-ansi \
  && poetry cache clear --all pypi --no-interaction || true \
  && rm -rf ~/.cache/pip

COPY . .
RUN pytest

# 运行时阶段
FROM python:3.13-slim-bookworm
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    LANG=C.UTF-8

WORKDIR /code

COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY --from=builder /usr/local/bin/gunicorn /usr/local/bin/gunicorn
COPY --from=builder /usr/local/bin/uvicorn /usr/local/bin/uvicorn

COPY --from=builder /code /code

基础优化结果:

| 指标 | 优化前 | 优化后 | 变化 |

|---------|------|-------|-----------|

Google AdInline article slot

| 镜像体积,MB | 894.84 | 508 | -43% |

| 完整构建时间,秒 | 58 | 315 | +443% |

| 编辑后构建时间,秒 | 56 | 16 | -71% |

首次构建因构建层而较慢,但缓存加速了迭代。

高级方法:Chainguard 与手动分析

Chainguard 镜像

Chainguard 排除 shell、apt/apk,最小化攻击面。基础镜像无 CVE。节省:50–150 MB。

缺点:

  • 无 shell 调试困难
  • 仅最新标签免费
  • 付费版本昂贵

适用于高安全性项目。

使用 dive 手动分析

分析层:

docker history --format "{{.CreatedBy}}: {{.Size}}" image:tag
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest image:tag

关注大型运行时层。折叠目录(Shift+Space),移除不必要的库。需要 Linux 专业知识,通常不划算。

极致优化:scratch

在 scratch 上运行——仅复制所需的 libc。体积降至 384 MB(比原始减少 57%,比多阶段减少 24%)。

缺点:

  • 调试不可能
  • 新依赖需手动添加库
  • 调试时间:1+ 小时

适用于数千个 Pod、Serverless(Knative、Fargate)。在 Python 中比 Go 更难。

体积对比:

  • 无多阶段:894 → 384 MB(-57%)
  • 多阶段:508 → 384 MB(-24%)

优化构建时间

在代码前复制 pyproject.toml/poetry.lock:

  • COPY pyproject.toml poetry.lock* ./
  • RUN poetry install
  • COPY . .
  • RUN pytest

依赖缓存随代码变更而持久。加速:58 → 14 秒(4 倍)。

关键要点

  • 多阶段 + 精简:-43% 体积,-71% 迭代时间。
  • .dockerignore + 无缓存:从运行时排除测试和缓存。
  • COPY 顺序:依赖缓存与代码分离。
  • Scratch:-57%,但适用于极端情况(数千个 Pod)。
  • Chainguard/dive:用于安全和微调。

— Editorial Team

Advertisement 728x90

继续阅读