Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是Docker构建阶段?_Docker_Dockerfile - Fatal编程技术网

什么是Docker构建阶段?

什么是Docker构建阶段?,docker,dockerfile,Docker,Dockerfile,据我所知,Docker中的构建阶段是最基本的,我对它们有实际的理解,但我很难给出正确的定义,而且我似乎也找不到一个 那么:Docker构建阶段的定义是什么 编辑:我不是问“我如何使用构建阶段?”或“我如何使用多构建阶段?”人们似乎非常渴望回答:-) 我之所以提出这个问题,是因为我在书中看到了以下句子: “FROM指令初始化新的生成阶段” “可以为新生成阶段指定名称” 这让我想知道:构建阶段到底是什么?自17版以来,docker现在在docker构建执行期间支持多个阶段 这意味着,您不再需要在

据我所知,Docker中的构建阶段是最基本的,我对它们有实际的理解,但我很难给出正确的定义,而且我似乎也找不到一个

那么:Docker构建阶段的定义是什么

编辑:我不是问“我如何使用构建阶段?”或“我如何使用多构建阶段?”人们似乎非常渴望回答:-)

我之所以提出这个问题,是因为我在书中看到了以下句子:

  • “FROM指令初始化新的生成阶段”
  • “可以为新生成阶段指定名称”

这让我想知道:构建阶段到底是什么?

自17版以来,
docker
现在在
docker构建执行期间支持多个阶段

这意味着,您不再需要在docker文件中仅定义一个源映像,并在一次运行中完成整个构建,而是可以在
Dockerfile
中为每个阶段定义多个具有多个
FROM
定义的不同映像的多个阶段:

# Build stage
FROM microsoft/aspnetcore
# ..do a build with a dev image for creating ./app artifact

# Publish - use a hardened, production image
FROM alpine:latest
CMD ["./app"]  
这为您提供了一个好处,可以打破您的图像构建过程,针对您在某个阶段中正在执行的任务进行优化,例如,这些阶段可以是:

  • 使用具有额外linting依赖项的图像检查源
  • 使用已安装了所有开发依赖项的开发人员映像来构建源代码
  • 使用包含测试框架的另一个映像在工件上运行各种测试
  • 一旦一切顺利,使用最小尺寸、优化、加固的图像来捕获最终工件以供生产
  • 阅读有关
    多级生成的更多详细信息


    我不认为会对Docker构建阶段有一个严格的定义,因为构建阶段通常是理论性的:

    • 可以由您定义
    • 取决于您的情况(语言/库)

    在这个问题上:其中一个答案是

    构建意味着编译项目

    我想你也可以这样看。构建阶段是任何生成稍后可以采用和使用的内容的过程

    docker多阶段构建的理念是:

  • 生成您需要的内容
  • 留下你不需要的东西,以更轻量级的方式使用步骤1中的产品
  • 如果您已经阅读了文档,Alex Ellis有一个很好的例子,其中发生了相同的逻辑:

  • 他从一个
    golang
    图像开始,添加库,构建他的应用程序(Go生成一个二进制可执行文件)
  • 之后,他不需要golang和库来发布/运行它,因此,他选择了一个
    alpine
    图像,添加步骤1中的可执行文件,并发布了一个小得多的图像
  • 舞台 名词
    过程或发展中的点、时期或步骤

    举一个实际的例子:您希望构建一个映像,其中包含一个生产就绪的web服务器,该服务器使用编译为Javascript的Typescript文件。您希望在Docker容器中构建该类型脚本以简化依赖关系管理。因此,您需要:

    • node.js
    • 打字稿
    • 编译所需的任何依赖项
    • 网页包之类的
    • nginx/Apache/随便什么
    在最终的图像中,您实际上只需要编译的.js文件和nginx。但要达到目的,你首先需要所有其他的东西。当您上传最终图像时,它将包含所有中间层,即使它们对于最终产品是不必要的

    Docker build Stage现在允许您将这些阶段或步骤实际分离到单独的图像中,同时仍然只使用一个Docker文件,而不需要将多个Docker文件与外部shell脚本或诸如此类的脚本粘合在一起。例如:

    FROM node as builder
    RUN npm install ...
    # whatever you need to build your files
    
    FROM nginx as production
    COPY --from=builder /final.js /var/www/html
    
    此Dockerfile的最终结果是一个以
    nginx
    为基础的小图像,外加最终的.js文件。它不包含所有不必要的东西,比如node.js和npm依赖项


    builder
    这里是第一个阶段
    生产
    是第二个阶段。在这种情况下,第一个阶段将在流程结束时被丢弃,但您也可以选择使用
    docker build--target=builder
    构建特定阶段。来自
    的新的
    引入了一个新的独立阶段。它们本质上是独立的DockerFile,但它们可以使用
    COPY--from

    共享数据。构建阶段从from语句开始,在下一from语句之前的步骤结束。在多阶段构建中,您将经历创建多个映像的过程,但是通常只标记单个映像(多个构建除外,使用buildx等工具构建多体系结构映像清单,以及docker在回答此问题后发布的任何其他内容)


    每个阶段都从Dockerfile中的
    from
    行开始,构建一个独特的图像。一个阶段不继承以前阶段中完成的任何操作,它基于自己的基础映像。因此,如果您有以下情况:

    FROM alpine as stage1
    RUN apk add your_tool
    
    FROM alpine as stage2
    RUN your_tool some args
    
    您将收到一个错误,因为您的_工具未在第二阶段安装


    您从构建中得到哪个阶段的输出?默认情况下,最后一个阶段,但您可以使用
    docker image build--target stage1来更改该阶段。
    以使用本例中的名称
    stage1
    来构建该阶段。经典docker构建将从Dockerfile的顶部运行,直到完成目标阶段。Buildkit构建一个依赖关系图并同时构建阶段,并且仅在需要时才构建,因此不要依赖于此顺序来控制yo中的测试工作流之类的东西
    FROM maven as build
    COPY src /app/src
    WORKDIR /app/src
    RUN mvn install
    
    FROM openjdk:jre as release
    COPY --from=build /app/src/target/app.jar /app
    CMD java -jar /app/app.jar
    
    FROM upstream as mybuilder
    RUN apk add common_tools
    
    FROM mybuilder as stage2
    RUN some_tool arg2
    
    FROM mybuilder as stage3
    RUN some_tool arg3
    
    FROM minimal_base as release
    COPY --from=stage2 /bin2 /
    COPY --from=stage3 /bin3 /
    
    FROM alpine
    COPY --from=docker:stable /usr/local/bin/docker /usr/local/bin/