Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Multi-Stage: How to split up into multiple Dockerfiles

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.

like image 413
Unapiedra Avatar asked Dec 06 '18 21:12

Unapiedra


People also ask

How do I build multiple Dockerfiles?

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.

Can you have multiple Dockerfiles in a project?

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

How does a multi-stage Docker work?

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.

How do I use multi stage builds in dockerfile?

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.

How do I copy a dockerfile from one stage to another?

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.

Can I have multiple dockerfiles in one directory?

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.

How to optimize dockerfiles to keep image size smaller?

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.


1 Answers

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.

like image 51
David Maze Avatar answered Sep 19 '22 15:09

David Maze