< Blog

Speed up your Docker builds using layer caching (avoid reinstalling dependencies)

One small problem I recently came across was a project that had a slow build time to run, ~7 mins approx. Config changes required a rebuild, so 7 mins per change. Something i noticed was npm packages being installed for config changes and even HTML changes - why do I need to download 1000+ npm packages if i'm only changing HTML? Madness!

Docker can cache commands but only if the Dockerfile is written in a certain way. Take the following scenario:

FROM node:9
COPY /src /src
RUN npm install
RUN npm run build

Docker can cache each command and create a Layer. Layers are cached if Docker detects that no files have been changed for that command.

By splitting the COPY into 2 commands, we can utilize caching and speed up the build time for builds that haven't modified npm packages:

FROM node:9
COPY /src/package*.json /src
# Docker will cache these 2 layers if package.json and package.lock.json are unmodified
RUN npm install

# copy the rest of our code and run a fresh build
COPY /src /src
RUN npm run build

Just by adding 1 line, we can speed up most of our builds - in my scenario it was local builds and CI server builds (npm packages rarely change in a mature project)

This 1 line Dockerfile change has saved our team a few minutes per build (we had some large / slow npm dependencies for things like integration testing such as cypress).

This is because Docker only reuses a cached layer if every file involved in that layer is unchanged. When you COPY . . before npm install, any HTML, JS, or config change invalidates the whole dependency layer.

That's all folks!

Enjoy my content? Want to buy me some snacks and support this hungry developer?
Buy Me A Coffee
< Blog