Cloud Native 7 min read

Optimizing Docker Build Times in Jenkins CI with Cache Strategies and BuildKit

This article details how to dramatically reduce Jenkins‑triggered Docker build times for a BI project by enabling Docker layer and application‑level caches, configuring webpack caching, and leveraging BuildKit mount‑type caches to persist node_modules, achieving an 80% speedup with minimal configuration changes.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Optimizing Docker Build Times in Jenkins CI with Cache Strategies and BuildKit

Background: A BI project built on Jenkins routinely took over 20 minutes per build, even for a single line change, prompting a need for speed optimization.

Build flow analysis: developers push code to GitLab, triggering GitLab push events, which invoke Jenkins webhooks to start the build; the build pulls source code, runs docker build to create an image, uses npm scripts to build the frontend, and copies the artifacts into an Nginx base image.

Optimization focus: the only significant time‑consuming step is the Docker image build, which can be accelerated by employing two types of cache – Docker layer cache and application‑level cache.

Docker layer cache reuses unchanged image layers defined in the Dockerfile, while application‑level cache preserves the node_modules directory and the .cache generated by npm install and npm run build . Enabling webpack’s cache (setting cache: true in webpack.config.js ) further reduces rebuild time.

module.exports = {
  // ...
  cache: true
};

Observed results: the first local build without cache took about 13 minutes; subsequent builds with cache consistently took around 4 minutes, regardless of source changes. However, webpack cache only applies in watch or development mode, so the main speedup came from react‑scripts internal caches (babel‑loader, eslint‑webpack‑plugin, terser‑webpack‑plugin) that store files in node_modules/.cache .

Persisting node_modules with BuildKit: using Docker 18.09+ and enabling BuildKit ( DOCKER_BUILDKIT=1 ) allows RUN --mount=type=cache to cache npm install and npm run build steps. The Dockerfile is modified to include mount directives, and the build command is prefixed with the environment variable.

DOCKER_BUILDKIT=1 docker build .
FROM node:alpine as builder
WORKDIR /app
COPY package.json /app/
RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
    --mount=type=cache,target=/root/.npm,id=npm_cache \
    npm i --registry=https://registry.npm.taobao.org
COPY src /app/src
RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
    npm run build

Optimization outcome: after applying the cache strategies, the automated build time dropped from over 20 minutes to roughly 4 minutes, a reduction of about 80%, with only a single line change in Jenkins configuration and three lines added to the Dockerfile.

DockerCacheCI/CDWebpackJenkinsbuildkit
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.