← Back to Blog

Maximising Efficiency: Steps to Minimise Docker Build Time

Abisade Ogunwoolu·29 October 2023·4 min read

Introduction:

As a developer, it is crucial to have an efficient docker build process to save time and streamline the development and testing of applications. In this blog, we will explore various steps to optimise the dockerfile build process, reduce build time, install necessary dependencies, and create lightweight and efficient docker images.

The Initial Dockerfile:

# Single Build Stage
FROM node:latest
WORKDIR /app
COPY . .
RUN yarn install 
ENV DISABLE_ESLINT_PLUGIN=true NODE_ENV=production  
RUN yarn run build
EXPOSE 3000 
CMD [ "yarn", "start" ]

The Final Dockerfile:

# Define the ARGs at the top of your Dockerfile
ARG BASE_IMAGE=node:latest
ARG NGINX_IMAGE=nginx:latest

# -------------> Build Stage dev
FROM ${BASE_IMAGE} AS build-stage-dev
ENV DISABLE_ESLINT_PLUGIN=true
WORKDIR /app
COPY . .
RUN yarn install && yarn run build

FROM ${BASE_IMAGE} AS build-stage-prod
ENV DISABLE_ESLINT_PLUGIN=true
WORKDIR /app
COPY --from=build-stage-dev /app/node_modules ./node_modules
COPY . .
RUN yarn install && yarn run build

FROM ${NGINX_IMAGE} as deploy-stage-dev 
COPY --from=build-stage-dev /app/build /usr/share/nginx/html 
EXPOSE 80 
STOPSIGNAL SIGTERM 
CMD ["nginx", "-g", "daemon off;"]

FROM ${NGINX_IMAGE} as deploy-stage-prod 
ENV NODE_ENV production 
COPY --from=build-stage-prod /app/build /usr/share/nginx/html 
EXPOSE 80 STOPSIGNAL SIGTERM CMD ["nginx", "-g", "daemon off;"]

Analysing the Current Dockerfile:

The first step in minimising docker build time is to analyse the current dockerfile for potential bottlenecks or unnecessary steps. By identifying and eliminating these inefficiencies, we can significantly reduce the overall build time.

FROM node:latest
WORKDIR /app 
COPY . . // <--- This is the first bottleneck, as it copies all files including node_modules
RUN yarn install // <--- This is the second bottleneck, as it installs all dependencies
ENV DISABLE_ESLINT_PLUGIN=true NODE_ENV=production  
RUN yarn run build // <--- This is the third bottleneck, as it builds the application
EXPOSE 3000 
CMD [ "yarn", "start" ] // <--- This is the fourth bottleneck, as it starts the application using yarn

Optimising the Order of Steps:

Next, we can optimise the order of steps in the dockerfile to minimise build time. By rearranging the steps based on their dependencies and avoiding unnecessary repetition, we can streamline the build process and reduce the time it takes to create the docker image.

Utilising Multi-Stage Builds:

One effective technique to minimise build time is to use multi-stage builds. This approach involves separating the build environment from the production environment, resulting in a smaller final image size. By discarding unnecessary build dependencies and only including essential components in the production image, we can further optimise the build process.

# Build Stage
FROM node:latest AS build
WORKDIR /app
COPY . .
RUN yarn install 
ENV DISABLE_ESLINT_PLUGIN=true NODE_ENV=production  
RUN yarn run build

# Production Stage
FROM node:latest
WORKDIR /app
COPY --from=build /app .
EXPOSE 3000 
CMD [ "yarn", "start" ]

Caching Techniques:

Caching plays a crucial role in reducing build time. By utilising caching techniques, we can avoid re-installing dependencies that have not changed since the last build. This significantly speeds up the build process, especially when dealing with large dependencies.

Using Lightweight Base Images:

Another way to minimise docker build time is to consider using lightweight base images. By selecting a base image that is specifically designed for efficiency and minimal footprint, we can further reduce the size of the docker image. This not only speeds up the build process but also improves the overall performance of the application.

# Build Stage
FROM node:alpine AS build
WORKDIR /app
COPY . .
RUN yarn install 
ENV DISABLE_ESLINT_PLUGIN=true NODE_ENV=production  
RUN yarn run build

# Production Stage
FROM node:alpine
WORKDIR /app
COPY --from=build /app .
EXPOSE 3000 
CMD [ "yarn", "start" ]

Testing and Documentation:

After implementing the aforementioned optimisations, it is essential to thoroughly test the new dockerfile build process. This ensures that it meets the acceptance criteria and performs as expected. Additionally, documenting the changes made and the reasoning behind them is crucial for future reference and troubleshooting.

Conclusion:

By following these steps to minimise docker build time, developers can significantly enhance their productivity and efficiency. Optimising the dockerfile build process not only saves time but also improves the overall development workflow. With a streamlined and efficient build process, developers can focus more on developing and testing their applications, leading to faster iterations and better software quality.

DockerOptimising