Skip to content

perf(docker): cache image builds through cache mounts and GHA cache #4020

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 22, 2025

Conversation

AlexTMjugador
Copy link
Member

Overview

These changes improve the performance of our Docker image building process by enabling the reuse of cached results from previous runs in two ways:

  • The Cargo target and source checkout directories are now set up as cache mounts. This allows Docker's BuildKit to reuse these directories even if the build layer cache is invalidated, which usually happens due to changes in source files copied via a previous COPY instruction.
  • BuildKit caches are now stored externally as GitHub Actions cache artifacts, using a dedicated storage backend. This enables cache reuse across workflow runs.

The first improvement can significantly enhance the developer experience during local builds. The second builds upon the first to bring similar benefits to our CI environment.

That said, expectations on the CI case should be tempered. Accessing the GitHub Actions cache introduces some performance overhead, and we are already using the 10 GiB limit for cache artifacts. As a result, hit rates are expected to be low (<40%), and the overall speedup can be minimal. Still, there is no noticeable downside, and this setup offers an easy opportunity to gain speed improvements without additional compute. Combined with the improved local development experience, this seems like the right call to make.

@AlexTMjugador AlexTMjugador added backend Relates to Modrinth Backend or API DevEx Improvements to developer experience labels Jul 18, 2025
@AlexTMjugador AlexTMjugador marked this pull request as draft July 18, 2025 15:10
@AlexTMjugador AlexTMjugador marked this pull request as ready for review July 18, 2025 15:25
Copy link
Member

@clrxbl clrxbl 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 do wonder if we should be using registry mode caching instead as we wouldn't be running into Github storage limits this way and be able to cache more

@AlexTMjugador
Copy link
Member Author

LGTM but do wonder if we should be using registry mode caching instead as we wouldn't be running into Github storage limits this way and be able to cache more

You're right that's likely to be a better cache store to use. However, as far as I can tell, it requires publishing the image and locating previously published images by their tags, which can be quite inconvenient, and that's why I initially avoided it. Still, I'll give it a try and see if we can live with those requirements.

@AlexTMjugador AlexTMjugador force-pushed the alex/docker-build-caching branch from ae9f081 to 02253b7 Compare July 22, 2025 22:19
@AlexTMjugador
Copy link
Member Author

AlexTMjugador commented Jul 22, 2025

I dug a bit deeper into this, and it turns out that using pure registry caching would require publishing the cache to a separate image or tag. That feels a bit clunky, as we'd either end up exposing an internal implementation detail in our public registry, or pushing to different registries.

Instead, I've switched to using the inline cache storage backend, which stores the cache alongside the pushed image. The Docker documentation is unclear on what exactly "doesn't scale" with this backend in multi-stage builds, so I guess we'll have to try it out! The 10 GB cache GitHub offers definitely doesn't scale for monorepos anyway.

@AlexTMjugador AlexTMjugador enabled auto-merge July 22, 2025 22:26
@AlexTMjugador AlexTMjugador added this pull request to the merge queue Jul 22, 2025
Merged via the queue into main with commit bb9af18 Jul 22, 2025
5 checks passed
@AlexTMjugador AlexTMjugador deleted the alex/docker-build-caching branch July 22, 2025 22:49
IMB11 pushed a commit that referenced this pull request Jul 25, 2025
…4020)

* perf(docker): cache image builds through cache mounts and GHA cache

* tweak(ci/docker): switch to inline registry cache
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Relates to Modrinth Backend or API DevEx Improvements to developer experience
Development

Successfully merging this pull request may close these issues.

3 participants