Multi stage build in docker
Docker uses a special text file called a Dockerfile. Dockerfiles use a DSL to describe how to build a Docker image. This DSL is actually a series of commands that, when executed, assemble a Docker image. Users can issue the docker build command against the Dockerfile to perform an automated build that executes these command-line instructions in succession.
Building Image Using Dockerfile
*Start from the base image node:10
*There are two package.json files: one is for node js server and another is for Angular UI. We need to copy these into the Docker file system and install all the dependencies.
*Copy all the source files.
*Angular uses Angular/CLI to build the app. So, install CLI and install all the dependencies.
*Run npm run build to build the Angular App and all the assets will be created under dist folder within WebApp folder.
# cat Dockerfile
# set the work directory
# copy package.json
COPY package*.json ./
# copy webapp folder
COPY WebApp/package*.json ./WebApp/
# RUN npm install for node js dependencies
RUN npm install \
&& cd WebApp \
&& npm install @angular/cli \
&& npm install
# Bundle app source
COPY . .
# builing Angular UI
RUN cd WebApp && npm run build
Let’s build the image with the following command. It takes some time to build an image since we are installing two package.json dependencies and Angular/CLI.
#docker build -t nodewebapp:v1 .
With multi-stage builds, we can use multiple FROM statements to build each phase. Every FROM statement starts with the new base and leaves behind everything which we don’t need from the previous FROM statement.
Dockerfile for the multi-stage build.
FROM node:10 AS ui-build
COPY WebApp/ ./WebApp/
RUN cd WebApp && npm install @angular/cli && npm install && npm run build
FROM node:10 AS server-build
COPY --from=ui-build /usr/src/app/WebApp/dist ./WebApp/dist
COPY package*.json ./
RUN npm install
COPY index.js .
Let’s build the image with the following command
# docker build -t nodewebapp:v1 .
Sending build context to Docker daemon 2.048kB
Step 1/13 : FROM node:10 AS ui-build
10: Pulling from library/node
76b8ef87096f: Already exists
2e2bafe8a0f4: Already exists
b53ce1fd2746: Already exists
84a8c1bd5887: Already exists
7a803dc0b40f: Already exists
b800e94e7303: Already exists
0da9fbf60d48: Pull complete
04dccde934cf: Pull complete
73269890f6fd: Pull complete
Status: Downloaded newer image for node:10
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nodewebapp V1 813f48d8892b 2 minutes ago 910MB
nodereact test1 cc97727462bf 19 hours ago 1.87GB
In a multi-stage build, We can have as many stages as you want in one Dockerfile, multi-stage build, we can use --from flag to copy the files from one stage to another stage. We can have multiple stages in the multi-stage Dockerfile. We can stop at any particular stage with the flag—target as below.
#docker build --target ui-build -t webapp:v1 .
Docker introduced multi-stage builds from version 17.05, With multi-stage builds, we can have multiple stages and copies only layers which are necessary for the final image from the previous stage.