Tag Intermediate Build Stages (multi-stage build)

I’m interested in the ability to tag an intermediate build stage, and looking for suggestions.

I have 3 stages in my build:

  1. FROM node, Install prod node_modules
  2. FROM stage 1, install dev node modules including grunt/bower/etc and generate my static js and html files.
  3. FROM stage 1, copy the output from stage 2 and now I have a slim output container

However for development I prefer to run grunt inside a container - the intermediate grunt container is exactly what I need to execute grunt watch, except it is not given a tag and so would only be available by referencing the hash.

1 Like

For anyone that is interested in something similar, I’ve found a workaround for now.

Using the LABEL command in my dockerfile I added a label to the build stage I’m interested in, then filter for it later:

FROM node as builder-stage
LABEL builder=true

FROM node as app-stage
LABEL builder=false

Now to filter, sort newest first, cut out the date, and take the top row:
docker images --filter “label=builder=true” --format ‘{{.CreatedAt}}\t{{.ID}}’ | sort -nr | head -n 1 | cut -f2

Note that it is important to remove the label in the next build stage.

3 Likes

The label trick works very well, thanks for sharing!

I didn’t find the need to remove the label on the the second stage of the build, however.

1 Like

You can use the --target keyword to build just a specific stage:

docker build --target builder-stage -t builder-image .

4 Likes

The label trick also works great for me since I am building on a Jenkins machine used by multiple teams within the company, and I wanted to avoid using docker image prune to not accidentally delete something used by other people.

Thanks

Thanks for this!

I used it with these 2 Dockerfiles:

Then I ran:
docker images --filter "label=builder=true"

and got:

And when running docker images I get:

with the following docker build command for synapse :

docker build -t as/anconnector-synapse:master -f docker/Dockerfile .

btw I deleted those images then like this:

docker rmi $(docker images --filter=label=builder=true -q)

This won’t for me anymore.

I have the Dockerfile

# Phase 1: Build the source code
FROM nginx:latest AS build
WORKDIR /src
RUN echo "Build completed" > build.txt

# Phase 2: Run unit tests
FROM build as testrunner
WORKDIR /testresults
RUN echo "Placeholder" > placeholder.txt
RUN echo "Unit test completed" > testresults.txt
LABEL builder=true

# Phase 3: Publish the binary
FROM build as publish
WORKDIR /publish
COPY --from=build /src/build.txt .
RUN echo "Binary publish completed" > publish.txt

# Phase 4: Build the final docker image
FROM nginx:latest AS base
WORKDIR /app
COPY --from=publish /publish .
COPY --from=testrunner /testresults/placeholder.txt .

I build it with docker build -t testimage:dev ., after the build, I use docker images --filter "label=builder=true" to retrieve the intermediate image, the result is empty.

I’m running Docker Desktop for Mac on a Mac Mini M1, the version is 4.23.0 (120376).

Check the second post again:

As in

LABEL builder=false