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.
Let's say we have two Dockerfiles, one for building the backend and another for building the frontend. We can name them appropriately and invoke the build command two times, each time passing the name of one of the Dockerfiles: $ docker build -f Dockerfile.
As Kingsley Uchnor said, you can have multiple Dockerfile , one per directory, which represent something you want to build.
A multistage Docker build is a process to create a Docker image through a series of steps. Each stage accomplishes a task -- such as to load or remove build tools -- specific to the base Docker image, as part of the compilation process.
Use multi-stage builds. 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.
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.
Don't rename your Dockerfile to Dockerfile.db or Dockerfile.web, it may not be supported by your IDE and you will lose syntax highlighting. As Kingsley Uchnor said, you can have multiple Dockerfile, one per directory, which represent something you want to build. I like to have a docker folder which holds each applications and their configuration.
When each instruction executes in Dockerfile, a new layer adds to the image. Hence to optimize Dockerfiles so that we can keep image size smaller, we go for multi-stage builds in docker, making Dockerfiles easy to read and maintain. Docker has introduced multi-stage builds in its latest release.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With