使用--target标志构建多阶段Dockerfile会构建所有阶段,而不仅仅是指定的阶段

Chr*_*sco 8 docker

docker build docs中,您可以指定--target带有创建阶段名称的标志。另外,在多阶段构建文档中也指定了相同的内容。

构建映像时,不一定需要构建包括每个阶段的整个Dockerfile。您可以指定目标构建阶段。以下命令假定您正在使用以前的Dockerfile,但在名为builder的阶段停止:

$ docker build --target builder -t alexellis2/href-counter:latest .
Run Code Online (Sandbox Code Playgroud)

我只有一个Dockerfile来构建我的项目。它具有多个阶段:

# development
FROM node:carbon as development
...

# e2e tests
FROM node:carbon as puppeteer
...
COPY --chown=puppeteer:puppeteer --from=development /app /home/puppeteer
...

# prod build
FROM node:carbon as build
...

# prod image behind webserver
FROM nginx as prod
...
COPY --from=build /app/build /usr/share/nginx/html
...
Run Code Online (Sandbox Code Playgroud)

当我尝试通过以下prod步骤进行构建时:

docker build -t my-app --target prod .
Run Code Online (Sandbox Code Playgroud)

我看到它正在构建所有阶段的日志,导致构建需要很长时间。

我希望它仅构建我指定的目标(及其阶段“依赖关系”),以便先构建build阶段,然后构建prod阶段。

我做错了什么或我想念什么?

注意:我也意识到,也许我对多阶段构建的工作抱有错误的期望,但是文档表明这听起来好像您可以构建所需的目标而不是整个文件,所以我假设是这种情况。

小智 22

从Docker 18.09开始,您可以使用BuildKit。好处之一就是跳过未使用的阶段,因此您所需要做的就是使用DOCKER_BUILDKIT=1 docker build -t my-app --target prod .

  • @MarcellodeSales、@mikeweather——如果舞台已经建成,它看起来仍然使用缓存。`=> CACHED [prod 4/4]` 有没有办法只强制最后一个阶段(prod)不使用缓存但允许第一阶段使用缓存? (2认同)

tto*_*lak 6

docker build docs中,它表示When building a Dockerfile with multiple build stages, --target can be used to specify an intermediate build stage by name as a final stage for the resulting image. Commands after the target stage will be skipped.这意味着,当您指定--target版本时,您仅指定将要构建的最后一个目标,因此之前的所有目标都将包括在构建过程中。要构建多环境,您可能需要有两个Dockerfile。

  • 这是BuildKit的18.06(实验版)和18.09(发行版)之前的版本。在https://docs.docker.com/develop/develop-images/build_enhancements/中进行了解释 (2认同)