CI/CD Integration
Push images to Clipper from your CI pipeline.
GitHub Actions
1. Store your token as a secret
Create a token with image:push, image:pull, and repo:create scopes. Then add it as a GitHub Actions secret with a name like CLIPPER_CREDENTIALS.
2a. Build and push using BuildKit (recommended)
We recommend using Clipper’s BuildKit fork, which speaks our image format natively. It can directly push to the registry, avoiding a separate export.
name: Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up Docker Buildx, using Clipper
uses: docker/setup-buildx-action@v4
with:
driver-opts: image=clipperregistry/buildkit:latest
buildkitd-config-inline: |
[worker.oci]
snapshotter = "clipper-lazy"
- name: Log in to Clipper
uses: docker/login-action@v4
with:
registry: clipper.dev
username: token
password: ${{ secrets.CLIPPER_CREDENTIALS }}
- name: Build and push
run: |
docker buildx build \
--output "type=clipper,name=clipper.dev/myorg/myapp:${{ github.sha }},push=true" \
.
The clipper.dev/ prefix is optional, the clipper exporter defaults to clipper.dev when no registry is specified.
Caching across builds
There are two independent caches you can carry between CI runs, and Clipper’s BuildKit fork can persist both:
- The layer cache, which lets BuildKit skip whole build steps whose inputs are unchanged. This is the standard
--cache-from/--cache-to. - Cache mounts, the directories behind
RUN --mount=type=cache(package downloads, compiler caches). CI runners start clean, so these are normally lost between runs. Clipper persists them by addingmode=cache-mountto a separate--cache-from/--cache-topair.
For example, a Dockerfile that uses a cache mount for the Go build and module caches:
FROM golang:1.24 AS build
WORKDIR /src
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
go build -o /app ./cmd/app
Pass both caches in the same build, each pointing at its own tag so they do not collide:
- name: Build and push
run: |
docker buildx build \
--cache-from "type=registry,ref=clipper.dev/myorg/myapp:layercache" \
--cache-to "type=registry,ref=clipper.dev/myorg/myapp:layercache,mode=max" \
--cache-from "type=registry,ref=clipper.dev/myorg/myapp:gocache,mode=cache-mount" \
--cache-to "type=registry,ref=clipper.dev/myorg/myapp:gocache,mode=cache-mount" \
--output "type=clipper,name=clipper.dev/myorg/myapp:${{ github.sha }},push=true" \
.
mode=cache-mount is a Clipper extension, so it requires the clipperregistry/buildkit image from step 2a. It works with the other cache backends too:
- Registry:
type=registry,ref=<image-ref>,mode=cache-mount - GitHub Actions cache:
type=gha,scope=<scope>,mode=cache-mount(addrepository=${{ github.repository }},ghtoken=${{ github.token }}oncache-to) - Local directory:
type=local,dest=<path>,mode=cache-mountto export andtype=local,src=<path>,mode=cache-mountto import
2b. Alternate: Push with the Clipper CLI
If you can’t use BuildKit, you can build with standard Docker and push with the Clipper CLI. This is slower because the image must be converted after building.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- uses: clipper-registry/setup-clipper@v1
- name: Push to Clipper
env:
CLIPPER_CREDENTIALS: ${{ secrets.CLIPPER_CREDENTIALS }}
run: |
clipper push myapp:${{ github.sha }} clipper.dev/myorg/myapp:${{ github.sha }}
clipper push myapp:${{ github.sha }} clipper.dev/myorg/myapp:latest
Running tests inside a Clipper image
Use the Clipper Runner to run GitHub Actions steps inside a Clipper image via container: jobs:
jobs:
test:
runs-on: ubuntu-latest
container:
image: clipperregistry/runner:latest
env:
CLIPPER_MAGIC_IMAGE: clipper.dev/myorg/myapp:latest
CLIPPER_CREDENTIALS: ${{ secrets.CLIPPER_CREDENTIALS }}
steps:
- name: Download and unpack clipper image
run: /.clipper-runner/github-init
- run: make test
Other CI systems
The same approaches work anywhere. For BuildKit, configure docker buildx with the Clipper BuildKit image and docker login. For the CLI fallback, set CLIPPER_CREDENTIALS to your token (or a credentials JSON object). See Authentication for details.