How to optimize Docker build time.

How to optimize Docker build time.

TL;DR

  • Avoid breaking the build cache.
    • For COPY and ADD operations.
      • Place them as last as possible in the Dockefile.
      • Split operations into smaller steps when possible.
      • Locate operations in the Dockerfile from least likely to most likely to change.

How Docker builds works

Docker images are build by stacking layers created by the operations defined in the Dockerfile.

Some operations in a Dockerfile only modifies the image metadata like CMD and LABEL, others like the COPY, ADD and RUN operations, create a layer when executed and each layer only contains the differences from the layer before it.

COPY and ADD instructions are triggered when there are changes to the files in the path that they point, this causes the cache to be invalidated.

When this happens, all the instructions that are bellow the COPY or ADD instruction are also executed.

Let's say we have the following nodejs app Dockerfile.

Inefficient Dockerfile

FROM node:16.2-alpine3.11

WORKDIR /app

COPY . /app

RUN ["yarn"]

CMD [ "yarn","start" ]

Here docker will.

  • Copy all the files in the current path.
  • Run yarn to install the packages.
  • Start the application.

This will happen whether there are changes to the packages.json file or simply a new feature was added.

To avoid this, we can split the files that are less likely to change from the ones that can change frequently.

Improved Dockerfile

FROM node:16.2-alpine3.11

WORKDIR /app

COPY package.json yarn.lock /app/

RUN ["yarn"]

COPY ./src/ /app/src/

CMD [ "yarn","start" ]

Here packages will only be installed were there is a change to packages.json or yarn.lock, if we add a new feature to the src directory, this will only trigger the instructions bellow, which in this case is only CMD.

Hopefully the steps above can help you reduce your docker build times.

For more information check out the official Docker best practices guide.

Happy Coding.