Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a multi-stage Dockerfile with --target flag builds all stages instead of just the specified one

Tags:

docker

From the docker build docs, you can specify a --target flag with the name of the stage to build it. Also, the same is specified in the multi-stage build docs.

When you build your image, you don’t necessarily need to build the entire Dockerfile including every stage. You can specify a target build stage. The following command assumes you are using the previous Dockerfile but stops at the stage named builder:

$ docker build --target builder -t alexellis2/href-counter:latest .

I have a single Dockerfile to build my project. It has multiple stages:

# 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
...

When I try to build for prod stage with:

docker build -t my-app --target prod .

I see the logs that it is building all the stages, causing the build to take very long time.

I want it to build just the target I specify (and its stage "dependency"), so that it builds the build stage and then the prod stage.

What am I doing wrong or what am I missing?

Note: I am also aware that maybe I have wrong expectations about what the multi-stage build does, but the documentation makes it sounds as if you can build the target you want instead of the whole file so I'll assume that's the case.

like image 534
Christopher Francisco Avatar asked Jul 09 '18 21:07

Christopher Francisco


People also ask

What is multistage build in Dockerfile?

A multistage build allows you to use multiple images to build a final product. In a multistage build, you have a single Dockerfile, but can define multiple images inside it to help build the final image.

Why use multi-stage builds docker?

With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don't want in the final image.

What is docker build target?

In docker build docs it says 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.

Can a project have multiple Dockerfiles?

As Kingsley Uchnor said, you can have multiple Dockerfile , one per directory, which represent something you want to build.


2 Answers

As of Docker 18.09 you can use BuildKit. One of the benefits is skipping unused stages, so all you should need to do is build with DOCKER_BUILDKIT=1 docker build -t my-app --target prod .

Reference

like image 53
mikeweather Avatar answered Oct 10 '22 19:10

mikeweather


In docker build docs it says 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.

This means, that when you specify --target option, you only specifying the last target which will be built so all before that will be included in the build process. To build multiple environments you probably need to have two Dockerfiles.

like image 22
ttomalak Avatar answered Oct 10 '22 19:10

ttomalak