Skip to content

Docker

Avrea accelerates Docker builds by serving BuildKit's type=gha cache backend from a colocated cache instead of GitHub's remote blob storage.

Repositories with persistent disks available can enable Docker cache on persistent disk under repository cache settings. Enable persistent disks for Linux first. The setting defaults off and takes effect on subsequent jobs that receive a disk.

This preserves Docker images, local build cache, and Docker volumes on the repository's persistent disk. Plain docker build and the default Docker builder reuse their cache automatically. For a container-based Buildx builder, use a stable builder name and retain its state:

workflow.yml
- uses: docker/setup-buildx-action@v4
with:
name: project-build
keep-state: true

Use different stable names for independent builders. Without keep-state, the setup action removes its BuildKit state during cleanup. Remote type=gha caching can still be used alongside disk caching.

The first run starts with an empty Docker store. Cache generations are separated by guest architecture, OS version, Docker version, and containerd version, so image upgrades can start a new cache. Unsupported images, unavailable disks, and insufficient setup time or free space fall back to the image's normal Docker storage. The initial implementation supports Linux guests using the external containerd image store and overlayfs snapshotter.

If a cached store cannot start, Avrea restores ordinary Docker and marks that cache generation unusable. After a successful rollback, other disk content can still be published, and later jobs skip the failed generation. A runtime image upgrade can create a fresh generation. Failure to restore Docker safely stops the VM and prevents publication.

The cache follows the disk's existing branch publication policy. Disposable jobs can read the published cache but cannot update it. Concurrent writers do not merge their changes: a stale writer's new cache entries can be discarded. Containers and temporary Docker networks are removed after job cleanup; images, build cache, and volumes remain. Docker client login credentials stay on the ephemeral runner filesystem.

Job changes to /etc/docker/daemon.json stay on the ephemeral filesystem. They do not prevent disk publication after both Docker stores are safely stopped and unmounted.

The default builder receives a garbage collection budget of half the disk size, capped at 20 GiB, unless the image already configures its own GC policy. Container-based builders use their own GC settings. This budget is not a quota on pulled images or Docker volumes; monitor free space and manage those through Docker. Disabling either setting retains existing disk data.

Use the standard docker/build-push-action with the type=gha cache backend, pointing it at the colocated cache via url_v2:

workflow.yml
jobs:
build:
runs-on: avrea-ubuntu-latest-2-vcpu
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- uses: docker/build-push-action@v7
with:
context: .
cache-from: type=gha,url_v2=https://cache.avrea.com/
cache-to: type=gha,url_v2=https://cache.avrea.com/,mode=max

On the first run, BuildKit builds all layers and exports them to the cache. On subsequent runs with unchanged inputs, every RUN step hits the cached layer and the build completes in seconds.

  • mode=max exports all layers, including intermediate build stages. Required for multi-stage builds (e.g. a build stage that compiles your app and a scratch/alpine final stage).
  • mode=min (default) exports only the final image layers. The build stage is not cached and must re-execute on every run.

Use mode=max unless you have a specific reason not to.

If you have multiple Dockerfiles or matrix builds, use scope= to isolate their caches:

cache-from: type=gha,url_v2=https://cache.avrea.com/,scope=backend
cache-to: type=gha,url_v2=https://cache.avrea.com/,mode=max,scope=backend

Add .git to your .dockerignore — otherwise COPY . . invalidates the layer cache on every run because .git/ contains files with different timestamps even when the same commit is checked out.

.dockerignore
.git