Skip to content

Conversation

orthodoX
Copy link
Contributor

@orthodoX orthodoX commented Sep 9, 2025

Why?

Every single time our deploy task is ran in CI we are performing a docker build from scratch and wait 3+ minutes for every deployment task. Just as we do for development, we can use Docker's build cache to drastically speed up this process by reusing unchanged layers from previously built images. The test I ran on staging completed a deploy in 13s!

deploy-cache-second

More context

For multistage Dockerfile definitions that we do for production, this requires registry cache strategy to be used, where cache artifacts are saved independently from the Docker image used to deploy the apps (which is a win win for us). A requirement for registry strategy is docker buildx driver instead of the default docker build.

The caching strategy implemented in this PR looks like this:

  • For the main branch, import main cache only and export main cache only
  • For other branches: import main cache + branch cache, export branch cache only - this multi import allows us to still reuse most of the cache (if not all) for freshly created branches which in the first CI run still do not have branch specific cache of their own

When exporting cache the mode=max param is passed, which yields the maximum cache hit ratio for layers. The size of these cache artifacts are ~700MB per file. We'll generate 1 file for main branch and 1 for every other branch. We can experiment with other modes, like mode=min to see the file size and cache hit ratio, if we think that size is a concern.

After a successful build when new cache artifact get pushed, the previous artifact for that branch automatically becomes stale and untagged in the ECR. And since these stale/untagged files are of no use to us, we'll prune them at the end of every build. Here's how these stale artifacts appear in ECR, just as a - 👇🏻

Screenshot 2025-09-11 at 10 15 35

Conclusion 🚀

By paying some price in ECR storage we can get almost instantaneous deploys, well worth trade imo. And with better defined ECR cleaning policies, we can free up space regularly by removing branches and cache artifacts every N amount of days that we agree on.

@orthodoX orthodoX force-pushed the adding-docker-build-cache branch 7 times, most recently from 54b032a to 11a9227 Compare September 11, 2025 13:41
@orthodoX orthodoX force-pushed the adding-docker-build-cache branch 4 times, most recently from 9c472f2 to 0e239c7 Compare September 11, 2025 22:52
@orthodoX orthodoX force-pushed the adding-docker-build-cache branch from 0e239c7 to 4c98ab1 Compare September 12, 2025 16:09
@orthodoX orthodoX marked this pull request as ready for review September 12, 2025 16:20
Copy link

@epaune-alt epaune-alt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but bash scripts and docker are not my strong points. Aleks and Adrian could be more helpful here. And maybe Alex E?

@orthodoX orthodoX force-pushed the adding-docker-build-cache branch from 2372db3 to 45aad59 Compare October 8, 2025 15:14
@orthodoX orthodoX force-pushed the adding-docker-build-cache branch from 45aad59 to 13aa044 Compare October 8, 2025 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants