Advanced Dockerfiles: Multistage Build
Docker images usually built with dockerfile with instructions, dependencies, and build steps. Dockerfile instructions add layers to the docker image which increases the size of docker image. Also for some deployment, we need to install the same dependencies repetitively.
By having multi-stage build we can make smaller, more optimized images, easy to read and maintain. The first stage can install dependencies, build the application. In the second stage we can deploy application using a smaller base image.
With multi-stage build, we can use multiple FROM statements. Each FROM instructions can use a different base image.
- Multi Stage Build: By default, the stages are not named, and you can refer to them by their integer number, starting with 0 for the first FROM instruction.
FROM node:14 ADD . /app WORKDIR /app
RUN npm install #second stage
FROM node:latest COPY --from=0 /app /app <------- Copies the built artifact from the previous stage into this new stage WORKDIR /app EXPOSE 8080 CMD ["server.js"]
- Name your build stages: You can name your stages, by adding an AS <NAME> to the FROM instruction.
FROM node:14 AS builder <---------- Stage Name ADD . /app WORKDIR /app RUN npm install #second stage FROM node:latest COPY --from=builder /app /app <------- Copies the built artifact from the previous stage into this new stage WORKDIR /app EXPOSE 8080 CMD ["server.js"]
- Using images directly: You can use external image as stage.
FROM scratch COPY --from=linuxkit/ca-certificates / /
- Inheriting from a stage: You can use a previous stage as a new stage. Same like --from=stage you can add FROM stage.
FROM ubuntu AS base RUN apt-get update && apt-get install -y vim git FROM base as stage1 RUN git clone .. FROM base as stage2 RUN git clone ..
- Combine above patterns: We can use above mentioned combined patter and create a minimal production image.
FROM ubuntu AS base <----------------- Using AS RUN apt-get update && apt-get install -y vim git FROM base as stage1 <--------- Inheriting from a stage RUN git clone abc FROM base as stage2 RUN git clone xyz FROM scratch
COPY --from=stage1 /abc /abc <-------------------Using --from=stagename COPY --from=stage2 /xyz /xyz
Build specific build stage: You can build specific build stage from dockerfile. When you are building you docker image, not necessarily to build the entire Dockerfile including every stage. This is useful for debugging the stage. You can easy debug any stage using this method by avoiding building entire dockerfile.
docker build --target stage2 -t deployingstage:latest . docker build --target stage3 -t productionstage:latest .
Reference: For more details, you can check official Advanced Dockerfiles and Multi-stage Build
PS: Please don't copy-paste this article. If you find it useful please feel free to share it, and yes don't forget to give credits.
Staff Engineer at VMware
3 年Very Informative !!!