Skip to content
intermediate Phase 9 · Docker CI/CD Integration

CI/CD Image Building

Build Docker images in CI/CD with proper caching and tagging.

1h
0 problems
Topic Progress 0%

Building on Ephemeral Runners

Building on Ephemeral Runners

CI machines are throwaway, so the local builder cache is gone every run. Use BuildKit through buildx and store layers in a shared backend:

docker buildx build   --cache-from type=gha   --cache-to   type=gha,mode=max   --tag app:${GITHUB_SHA::8}   --file Dockerfile .

mode=max exports every intermediate layer, not just the final stage — without it, npm ci layers from earlier stages never survive between runs. Build the image even when you will not push it: a build step on pull requests catches broken Dockerfiles before merge.

Tagging and Release Builds

Tagging and Release Builds

Derive tags from git so every image maps to a commit:

SHA=$(git rev-parse --short HEAD)
docker buildx build   --tag registry.example.com/app:$SHA   --tag registry.example.com/app:latest   --push .

latest is convenience for humans; automation should pin the SHA tag or digest. For multi-arch releases, add --platform linux/amd64,linux/arm64 with QEMU registered — the result is a manifest list, and one tag serves both architectures. Attach provenance with --provenance=true so consumers can verify what was built and from which source.

Pitfalls and Interview Angles

Pitfalls and Interview Angles

Cache misses after the first COPY. Adding COPY . . early invalidates every later layer on each commit — order the Dockerfile so dependency install runs before source copy.

Secrets in build args. --build-arg TOKEN=... is recorded in image history and visible to anyone who pulls it; use BuildKit --mount=type=secret instead.

Built is not tested. Run unit tests in the pipeline before the build, then smoke-test the built image (start the container, hit /healthz) — the image is the artifact that ships.

Interview: explain the buildx cache backends you would choose (gha for GitHub, registry for portability), where mode=max matters, and how you would prove a rebuild reused cache.

Quiz

1. Why use --cache-to type=gha,mode=max in GitHub Actions?

Question 1 options

2. Where should the dependency install step sit relative to COPY . .?

Question 2 options

3. Why not pass secrets as --build-arg?

Question 3 options

Flashcards

Question

Ephemeral runner cache

Answer

Local builder cache is lost per job — export/import via type=gha or type=registry.

Question

cache-to mode=max

Answer

Exports every intermediate layer, not only final-stage layers.

Question

Layer ordering rule

Answer

Least frequently changing instructions first: package manifests → install → source copy.

Question

--mount=type=secret

Answer

BuildKit secret exposed only to the RUN step that mounts it; absent from layers and history.

Revision Notes

Key Takeaways

  • 1. CI builds need a remote cache backend or they rebuild everything each run
  • 2. Order the Dockerfile by change frequency, not by reading convenience
  • 3. Tag from git SHA and verify the built image, not just the repo

Interview Tips

  • • Walk your Dockerfile line by line and defend each layer boundary against cache invalidation
  • • Explain the difference between image cache backends and where secrets must live

Cheat Sheet

buildx + --cache-from/to type=gha (mode=max); COPY package* then npm ci then COPY .; SHA tags; --platform for manifest lists; secrets via type=secret mounts.

Continue Learning

Before You Start

  • No prerequisites listed.