I came across a video about tips and tricks for Docker. In this video, the she gives us tips on how to utilize Docker cache layers. The main point is that Docker images have multiple layers, and each layer is cached by Docker. When there is a change in one layer, the layer below it will be invalidated.
Now, let’s examine our production Docker file. We can see that the layer is not optimized because we copy our code and then install the package. This can slow down the build process because if we change one file on our server app.
FROM node:18-alpine as builder
WORKDIR /main
COPY packages/libs packages/libs
COPY packages/validation packages/validation
COPY apps/server apps/server
COPY package.json .
COPY yarn.lock .
RUN yarn install --pure-lockfile --cache-folder ./yarncache; rm -rf ./yarncache;
RUN yarn workspace server build
RUN yarn install --production --pure-lockfile --cache-folder ./yarncacheprod; rm -rf ./yarncacheprod;
FROM node:18-alpine as runner
WORKDIR /main
COPY --from=builder /main/packages ./packages
COPY --from=builder /main/apps ./apps
COPY --from=builder /main/node_modules ./node_modules
COPY --from=builder /main/package.json ./
Now, let’s try to test it; first, let’s add some changes to our file.
Then let’s build the Docker file.
We can see the build time is more or less 32 seconds. Now let’s add more changes and see whether the build is actually cached or not.
Then let’s build the Docker file one more time.
Now let’s build the Docker file for the last time without change anything and see if the duration will be similar or not.
As we can see, when Docker utilizes its cache, the build time goes down to 2 seconds. So, we have already proven that changing the file content will invalidate the cache.
Optimizing the Layer Cache
To optimize our Dockerfile, we should consider which layer frequently changes and which layer takes longer to build. Then, we rearrange those layers to make sure that the frequently changed layer is placed at the bottom of the Dockerfile.
Now let’s see the Dockerfile after we optimized it.
The main change that we made is to copy the package.json
file, then we do the installation process after that. Although we do installation again after the build process, this installation will be faster because it only removes the files that are not for production mode.
Performance Test after Optimization
First, let’s create some changes in our file.
Then, let’s try to build the Dockerfile.
Then, let’s create another change.
Lastly, let’s build the Dockerfile again.
As we can see, after we changed the Dockerfile, the build time went down from 30 seconds to 11 seconds every time we built the image. One caveat for this method: if we have changes in package.json
, then Docker needs to invalidate all the layers after that. You can see the code for this part here
Top comments (1)
I love Using Docker Cache Layer to Speed Up Build Time