Skip to content

Comments

Optimize Docker builds with BuildKit cache mounts and registry caching#56

Closed
binarypie wants to merge 4 commits intomainfrom
claude/optimize-docker-layering-KFWif
Closed

Optimize Docker builds with BuildKit cache mounts and registry caching#56
binarypie wants to merge 4 commits intomainfrom
claude/optimize-docker-layering-KFWif

Conversation

@binarypie
Copy link
Collaborator

Summary

This PR enhances Docker/Podman build performance by implementing BuildKit cache mounts for package managers and adding registry-based build cache persistence across CI/CD runs.

Key Changes

CI/CD Workflow Updates

  • build-ai-dev.yml & build-nvim-dev.yml: Enhanced cache strategy to use both GitHub Actions cache and registry-based caching
    • Added type=registry cache source/destination for persistent build cache across runs
    • Maintains type=gha for faster local CI caching
    • Enables faster rebuilds by reusing downloaded artifacts from previous builds

Containerfile Optimizations

Both Dockerfiles (ai-dev & nvim)

  • Added # syntax=docker/dockerfile:1 directive to enable BuildKit features
  • Implemented cache mounts for package managers to persist downloads across layer-busting rebuilds

nvim/Containerfile (comprehensive optimization)

  • System packages layer: Added --mount=type=cache,target=/var/cache/dnf to cache RPM downloads
  • Homebrew setup:
    • Set explicit UID (1001) for linuxbrew user to match cache mount permissions
    • Added HOMEBREW_CACHE environment variable
    • Removed manual dnf clean all (cache mount handles cleanup)
  • Brew operations: Added cache mounts to all brew install and brew update commands
  • Language tools:
    • Go: Cache mount for Go module cache
    • Python: Cache mount for pip cache
    • Rust: Cache mount for Homebrew cache during rustup installation
    • Node.js: Cache mount for npm cache
  • ai-dev/Containerfile: Added cache mount for npm installation

Build Script Updates

  • nvim/Justfile: Updated build commands with clarified comments
    • build: Added --layers flag for explicit layer caching
    • build-no-cache: Clarified that download caches persist even with --no-cache

Implementation Details

  • Cache mounts use uid=1001,gid=1001 to match the linuxbrew user, preventing permission issues
  • Registry caching uses a :buildcache tag to avoid polluting the main image tags
  • BuildKit syntax directive enables modern Dockerfile features like cache mounts
  • Changes are backward compatible with existing build processes

Add persistent cache mounts for all package managers (dnf, Homebrew, Go,
pip, npm) so downloads survive layer invalidation. The daily dnf update
no longer triggers a full re-download of every package - only changed
packages are fetched.

Also adds registry-based build cache as a fallback for when the GHA
cache is evicted, ensuring CI builds always have layer cache available.
The ai-dev container inherits from the published nvim-dev:latest where
linuxbrew has a system-assigned UID (not 1001). The cache mount with
uid=1001 created a directory the linuxbrew user couldn't write to.

For a single package install the cache mount adds negligible benefit,
so remove it entirely.
The type=registry cache-to requires push auth which isn't available on
PR builds (login step is skipped). Unlike GHA cache, BuildKit's registry
exporter fails the entire build rather than degrading gracefully.

The GHA cache with mode=max already caches all intermediate layers and
is sufficient for the current workflow.
BuildKit cache mounts create intermediate parent directories as root.
This prevented go install from writing to $GOPATH/bin and npm from
writing to ~/.npm (for locks/logs), since both ran as linuxbrew.

Pre-create these directory trees before the cache-mounted layers so
they're owned by linuxbrew (uid 1001).
@binarypie binarypie closed this Jan 26, 2026
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