21

I am successfully using Docker's Multi-Stage feature to build some code and then copy the resulting artifacts into a final image.

Is it possible to split this one big-ish Dockerfile into multiple files?

I would like to improve the readability of the individual stages. Which will become more important when more stages are added.

EDIT: I am aware that I could write a Makefile (or similar) where I first build an image named "myproject-stage1" and then use FROM myproject-stage1 AS build. However, I'd rather avoid the external build tool if possible.

Unapiedra
  • 15,037
  • 12
  • 64
  • 93
  • I am absolute noob in this regard. Also, I have the feeling it is a duplicate question -- but I could not find anything related. – Unapiedra Dec 06 '18 at 21:33

1 Answers1

11

If your Dockerfile currently looks something like:

FROM ubuntu:16.04 AS builder
RUN apt-get install build-essential
COPY . ./
RUN ./build_all_the_things \
 && make install PREFIX=/usr DESTDIR/out

FROM alpine:3.8
COPY --from=builder /out/ /
CMD the_app

You can readily split out the first part into its own Dockerfile, as is, and build it

docker build -f Dockerfile.builder -t me/builder .

COPY --from has to name some previous stage in your Dockerfile, but the stage doesn’t need to do much; you can then change the second half of this to

FROM me/builder AS builder
FROM alpine:3.8
COPY --from=builder /out/ /
CMD the_app

The big downside of this is that you need two separate docker build commands to actually build the final image. You could write a shell script to do both of them together.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • 1
    This is just the builder pattern, right? In my EDIT I had already addressed this option. Do you know of any alternatives? Is there such a thing as `IMPORT Dockerfile.builder` – Unapiedra Dec 07 '18 at 06:44
  • Not natively. In principle you could use some other templating tool like m4 that has some sort of `include` call to generate the Dockerfile. – David Maze Dec 07 '18 at 11:04
  • 3
    According to [the docs](https://docs.docker.com/develop/develop-images/multistage-build/#use-an-external-image-as-a-stage): "When using multi-stage builds, you are not limited to copying from stages you created earlier in your Dockerfile. You can use the COPY --from instruction to copy from a separate image, either using the local image name, a tag available locally or on a Docker registry, or a tag ID" – DrMeers Jul 12 '19 at 01:26