首页 > 解决方案 > 下面这个例子中 docker 多阶段构建的优势是什么(为什么要这样做?)

问题描述

谁能解释多阶段构建的优点,尤其是在这个特定的Dockerfile示例中发生了什么?

参考:标题为: 从替代基础图像创建图像的部分


问题:

这种方法有什么优势:

FROM python:buster as build-image
ARG FUNCTION_DIR="/function"

<instructions>

FROM python:buster
# Copy in the build image dependencies
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}
<more instructions>

通过这种方法

FROM python:buster
<all needed instructions>

我没有看到优势,或者为什么会采用这种方法,但我不怀疑这种方法有一些优势。


来自上面链接的 Dockerfile 副本

# Define function directory
ARG FUNCTION_DIR="/function"

FROM python:buster as build-image

# Install aws-lambda-cpp build dependencies
RUN apt-get update && \
  apt-get install -y \
  g++ \
  make \
  cmake \
  unzip \
  libcurl4-openssl-dev

# Include global arg in this stage of the build
ARG FUNCTION_DIR
# Create function directory
RUN mkdir -p ${FUNCTION_DIR}

# Copy function code
COPY app/* ${FUNCTION_DIR}

# Install the runtime interface client
RUN pip install \
        --target ${FUNCTION_DIR} \
        awslambdaric

# Multi-stage build: grab a fresh copy of the base image
FROM python:buster

# Include global arg in this stage of the build
ARG FUNCTION_DIR
# Set working directory to function root directory
WORKDIR ${FUNCTION_DIR}

# Copy in the build image dependencies
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}

ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
CMD [ "app.handler" ]

标签: dockeraws-lambdadocker-multi-stage-build

解决方案


一个完整的 C 工具链是相当大的;猜测一下,如果您安装、和所需的 C 头文件,基于 Ubuntu 的python映像的大小可能会增加三倍。您只需要此工具链来构建 C 扩展,但一旦构建就不需要它。g++make

所以这里的多阶段构建分为两部分:

  1. 安装完整的 C 工具链。使用 C 扩展构建 Python 包并将它们放在已知目录中。这是非常大的,但只是一个中间步骤。
  2. 从没有工具链的普通 Python 图像开始,并从第一个图像复制构建的库。它的大小更适中,最终运行和重新分配。

这是多阶段构建的非常典型的用法,您可以在许多语言中看到与它的相似之处。在 Go 中,您可以有一个构建静态链接二进制文件的第一阶段,然后是一个仅包含二进制文件而不包含编译器的最后阶段;在 Node 中,您可以有一个包含 Typescript 编译器之类的第一阶段和一个仅包含生产依赖项的最后阶段;等等。


推荐阅读