A project I worked on recently had a ~7 minute Docker build time. 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! There is a simple solution to this.
How Docker layer caching works
Docker will 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:22-alpine
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
The Result
One extra line saved our team several minutes per build - in my scenario it was local builds and CI server builds (as npm packages rarely change in larger/mature project).
This pattern also works for any package manager: swap package.*json and npm install to align with your package manager (dotnet restore, bundle install, pip install etc)
Latest comments (0)