Urgent.News

One page, thousands of outlets. See who else covered it.

Editions

Tech

Why Your Docker Build Takes 11 Minutes in CI When It Takes 20 Seconds Locally

If your Docker build is fast locally and slow in CI, the base image is almost never the problem. CI runners are ephemeral, so they start with an empty layer cache unless you explicitly wire one up, and a COPY . . placed above your dependency install throws away whatever cache you did manage to restore. Fix the layer ordering first, then attach a cache backend, and measure with --progress=plain so…

Docker builds often take longer when run in CI compared to local development environments. The issue usually lies with the cache, not the base image. CI runners start with an empty cache, meaning COPY . . placed at the top of the Dockerfile clears any previous cache layers. To improve caching efficiency, move dependency installation steps to the bottom of the Dockerfile, after copying the manifest and lockfile.

This way, changes to code won't invalidate previous cache layers. Use --progress=plain when running docker build to identify which steps are actually cached. A common mistake is switching to a lighter base image like node:22-alpine without considering the cache implications. Image size affects push and pull times, but cache hits directly impact build time.

The Dockerfile should be ordered so that rarely changing layers are at the top, while frequently changing layers are at the bottom. For example, copy package.json and package-lock.json first, then install dependencies, and finally copy the source code. Python projects should follow a similar pattern with requirements.txt and Pip.

Ensure the .dockerignore file does not unintentionally include .git or node_modules. If the Dockerfile uses .dockerignore or writes timestamps into early layers, this invalidates subsequent layers. To make cache survive between CI runs, use BuildKit's cache-from and cache-to directives to export and import the cache using external backends.

GitHub Actions offers a built-in cache backend, while any CI provider can use a registry cache. Depot is a managed solution that handles persistent cache volumes. Cache mounts can speed up builds if the builder is long-lived. However, cache mounts do not persist across CI runs, so they should be used in conjunction with proper layer ordering and external caching.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Building Resilient Background Jobs in NestJS with BullMQ

Background jobs look simple right up until one of them dies silently in production and nobody notices for three days. A job that sends confirmation emails stops running.

  • BullMQ tutorials focus on basics, lacking real-world resilience patterns
  • Implement exponential backoff with jitter to prevent thundering herd
  • Use idempotency keys to ensure retries are safe and avoid duplicates

Designing HTML Page Caching Changed How I Think About Caching

Long Story Short Designing HTML page caching in practice connected several concepts I had previously understood separately, such as TTL, browser caching, and where cache policies should live.

  • HTML page caching at work revealed broader system impact
  • CloudFront served as CDN, cached HTML pages including SSR data
  • TTL wasn't simple, required context-specific reasoning

More from Sunday 16 August →