tim@kolberger.eu
Photo by Lukas Blazek on Unsplash

Tutorial: Road to production - Reduce CI time with the docker builder pattern

To improve performance on CI systems we are going to separate the build step from the creation of our web server image. We can cache the build image in a docker registry to speed up the build time if some docker layer check sums match e.g. package.json has not changed since the last build.

# .docker/frontend/Dockerfile_builder
FROM node:10-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci
COPY . .

RUN npm run build
# .docker/frontend/Dockerfile
ARG builder
FROM ${builder} as builder
FROM nginx:mainline-alpine

COPY --from=builder /app/dist/ /usr/share/nginx/html
# .gitlab-ci/build-frontend.sh
#!/usr/bin/env sh

# stop script on error and log every executed command
set -ex

FRONTEND_IMAGE="frontend"
FRONTEND_IMAGE_BUILDER="${FRONTEND_IMAGE}_builder"

echo $CI_REGISTRY_PASSWORD | \
    docker login \
        -u $CI_REGISTRY_USER \
        --password-stdin $CI_REGISTRY

# Pull images from docker registry and ignore if they do not exist yet
docker pull ${FRONTEND_IMAGE_BUILDER} || true
docker pull ${FRONTEND_IMAGE} || true

# build the builder image
docker build \
    --cache-from ${FRONTEND_IMAGE_BUILDER} \
    -t ${FRONTEND_IMAGE_BUILDER} \
    -f .docker/frontend/Dockerfile_builder \
    .

# build the web server image and pass the name of the dependent image
docker build \
    --cache-from ${FRONTEND_IMAGE} /
    -t ${FRONTEND_IMAGE} /
    -f .docker/frontend/Dockerfile \
    --build-arg builder="$FRONTEND_IMAGE_BUILDER" \
    .

# push both images to a docker registry
docker push ${FRONTEND_IMAGE_BUILDER}
docker push ${FRONTEND_IMAGE}
© 2021 Tim KolbergerDatenschutzerklärung