My GPU inference image was 8GB. Building it in GitHub Actions took 14 minutes on the free runner. Pushing to OCIR took another 6 minutes. Twenty minutes of CI time for every commit to main. I was burning through GitHub Actions minutes and my team was complaining about slow deployments.
Docker Build Cloud offloads the build to Docker's remote builders. They have fast machines with big caches. My 14-minute build dropped to 3 minutes. The push stayed at 6 minutes (that's network, can't speed it up much), but total CI went from 20 minutes to about 9.
What Docker Build Cloud Is
It's a remote build service from Docker. Instead of building on your CI runner (which is usually a small VM with cold layer caches), you build on Docker's infrastructure. They cache your layers aggressively across builds.
You don't change your Dockerfile. You add one setup step to your CI pipeline and change the docker build command to use the cloud builder. That's it.
The Before Pipeline
This is what I had:
# .github/workflows/build.yml (before)
name: Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to OCIR
run: echo "${{ secrets.OCIR_TOKEN }}" | docker login iad.ocir.io -u "${{ secrets.OCIR_USER }}" --password-stdin
- name: Build image
run: docker build -t iad.ocir.io/${{ secrets.TENANCY }}/inference/vllm:${{ github.sha }} .
- name: Push to OCIR
run: docker push iad.ocir.io/${{ secrets.TENANCY }}/inference/vllm:${{ github.sha }}
Build: 14 min. Push: 6 min. Total: ~20 min.
The GitHub Actions runner starts fresh every time — no layer cache. Every apt-get install, every pip install, every go mod download runs from scratch on every build.
The After Pipeline
# .github/workflows/build.yml (after — with Docker Build Cloud)
name: Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: cloud
endpoint: "pmady/oci-builds" # your Build Cloud org/builder
- name: Login to Docker (for Build Cloud auth)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to OCIR
uses: docker/login-action@v3
with:
registry: iad.ocir.io
username: ${{ secrets.OCIR_USER }}
password: ${{ secrets.OCIR_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: |
iad.ocir.io/${{ secrets.TENANCY }}/inference/vllm:${{ github.sha }}
iad.ocir.io/${{ secrets.TENANCY }}/inference/vllm:latest
cache-from: type=registry,ref=iad.ocir.io/${{ secrets.TENANCY }}/inference/vllm:cache
cache-to: type=registry,ref=iad.ocir.io/${{ secrets.TENANCY }}/inference/vllm:cache,mode=max
Build: 3 min (layers cached on Build Cloud). Push: 6 min. Total: ~9 min.
The big difference is the driver: cloud in the Buildx setup. That sends the build to Docker's builders instead of running it on the GitHub runner. Their builders are faster machines and they persist your layer cache between builds.
Why the Build Is So Much Faster
Three reasons:
1. Persistent layer cache. On GitHub Actions, every build starts from nothing. On Build Cloud, my base image layers, dependency downloads, and compilation results are all cached from the previous build. Only the layers that actually changed get rebuilt.
2. Better hardware. Build Cloud builders have more CPU, more RAM, and faster disks than the free GitHub Actions runners. The compilation step alone runs 2-3x faster.
3. Parallel multi-platform builds. When I build multi-arch images (amd64 + arm64), Build Cloud runs both architectures in parallel on native hardware. No QEMU emulation. On GitHub Actions, the ARM build was emulated and took 4x longer.
Registry Cache on OCIR
I store the build cache in OCIR itself using the cache-to: type=registry option. This means:
- Build Cloud uses its own fast cache for immediate rebuilds
- The registry cache in OCIR acts as a secondary cache that any CI runner can pull from
- No external cache service needed
The cache image (vllm:cache) is separate from the production image. It contains all the intermediate layers and gets updated on every build. It's large (~3GB) but OCIR storage is cheap.
Multi-Arch With Build Cloud
This is where Build Cloud really shines. Building ARM images on GitHub Actions with QEMU was painfully slow:
# With Build Cloud — native ARM + AMD64 builds in parallel
- name: Build and push multi-arch
uses: docker/build-push-action@v5
with:
push: true
platforms: linux/amd64,linux/arm64
tags: iad.ocir.io/${{ secrets.TENANCY }}/myapp:${{ github.sha }}
| Build Type | GitHub Actions (QEMU) | Docker Build Cloud |
|---|---|---|
| AMD64 only | 14 min | 3 min |
| ARM64 only (emulated) | 45 min | 4 min |
| Multi-arch (both) | 50 min | 5 min |
The multi-arch build went from 50 minutes to 5 minutes. That's not an optimization, that's a category change.
Cost
Docker Build Cloud has a free tier (200 build minutes/month) and paid plans. For my usage (~50 builds/month averaging 3 minutes each = 150 minutes), the free tier covers it.
Compare that to what I was spending on GitHub Actions: 20 min × 50 builds = 1,000 minutes/month. The free tier has 2,000 minutes, so I wasn't paying, but I was burning through them fast. Now I use 150 minutes of Build Cloud (free) and ~300 minutes of GitHub Actions (for the push + deploy steps).
The Setup Cost
Getting Build Cloud connected to OCIR took about 15 minutes:
- Create a Docker Build Cloud builder in Docker Hub settings
- Add
DOCKERHUB_USERandDOCKERHUB_TOKENto GitHub secrets - Change the
docker/setup-buildx-actiondriver tocloud - Add the OCIR registry cache config
No infrastructure to manage, no self-hosted runners to maintain, no cache servers to run.
Pavan Madduri — Oracle ACE Associate, CNCF Golden Kubestronaut. GitHub | LinkedIn | Website | Google Scholar | ResearchGate
Top comments (0)