Self-Hosting Guide
August 15, 2026 · View on GitHub
This guide explains how to host your own Buildcage Docker image in a private GitHub repository. This is useful when you want to:
- Keep the build infrastructure private within your organization
- Control exactly which version of Buildcage is deployed and when updates are applied
- Meet compliance requirements that mandate use of an internal container registry
Note
The upstream image (ghcr.io/buildcage/docker) is verified at action startup via Sigstore, confirming it was built from the exact source commit of the release — sufficient provenance assurance for most use cases. Self-hosting adds operational overhead: keeping your fork in sync with upstream and managing your own signing pipeline.
Prerequisites
- A GitHub organization (any plan, including Free) to hold the private repository and its container package. Private packages are available on all plans, though GitHub Packages storage/transfer beyond the plan's included quota (shared with Actions artifacts) is billed — see GitHub Packages billing.
1. Import the Repository
Since forking creates a public repository, use GitHub's import feature to create a private copy.
- Go to github.com/new/import
- Enter the source URL:
https://github.com/buildcage/docker.git - Select your organization as the owner
- Set the repository name (e.g.,
buildcage) - Choose Private
- Click Begin import
2. Build and Publish the Docker Image
Your imported repository already contains the Build and Push Docker Image workflow (.github/workflows/docker-publish.yml). This workflow builds two images per release — one per proxy_engine (transparent and explicit), from docker/transparent/Dockerfile and docker/explicit/Dockerfile respectively — and publishes both to your repository's GitHub Container Registry (GHCR), each signed independently.
To trigger the build:
- Go to your repository on GitHub
- Navigate to Actions > Build and Push Docker Image
- Click Run workflow
Once complete, the images will be available at:
ghcr.io/<your_org>/buildcage:<version>
ghcr.io/<your_org>/buildcage:<version>-explicit
The setup action resolves the correct tag automatically based on the proxy_engine input — you
don't need to reference these tags directly in your own workflows.
3. Configure Package Visibility
The published package needs to be accessible from the repositories that will use it.
- Go to
github.com/<your_org>/buildcage/pkgs/container/buildcage - Click Package settings
- Under Manage Actions access, add the repositories that need to pull the image
4. Configure Actions Access
Allow other repositories in your organization to use the actions from your private repository:
- Go to your Buildcage repository's Settings > Actions > General
- Under Access, select Accessible from repositories in the '<your_org>' organization
5. Update Your Workflows
In the repositories where you want to use Buildcage, make two changes:
Add GHCR login step
Add a login step before the Buildcage setup, and ensure the job has packages: read permission:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Login to GHCR
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Start Buildcage
uses: <your_org>/buildcage@<40-char-sha> # vX.Y.Z
with:
proxy_mode: audit
# ... rest of your workflow
Note that uses: now points to <your_org>/buildcage@<40-char-sha> # vX.Y.Z instead of
buildcage/docker@.... Replace <40-char-sha> with the commit SHA of the release tag in
your fork. The same applies to the report action (<your_org>/buildcage/report@<40-char-sha> # vX.Y.Z).
Image provenance verification
The setup action automatically verifies the Docker image's build provenance before pulling it. When you fork the repository:
- The
docker-publish.ymlworkflow in your fork will sign images with your fork's GitHub Actions OIDC identity. - The setup action will verify against your fork's workflow identity, so verification passes correctly.
- If you use
uses: <your_org>/buildcage@<40-char-sha>,github.action_repositoryresolves to<your_org>/buildcageand the image is pulled fromghcr.io/<your_org>/buildcageautomatically.
Note
The buildcage_image and buildcage_version parameters have been removed as of v2.1.
External image overrides are no longer supported because they would bypass the provenance
verification that guarantees image integrity. Self-hosting via fork is the supported alternative.
If provenance verification fails, the action will exit with an error. Make sure you have published at least one signed release in your fork before using a version tag.
You can independently confirm that a specific image digest has a valid signature using standard signing tooling, e.g. the cosign CLI:
cosign verify \
--certificate-identity-regexp "^https://github.com/<your_org>/buildcage/.github/workflows/docker-publish.yml@refs/tags/.*$" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/<your_org>/buildcage@sha256:<digest>
Syncing with Upstream
Initial setup
Clone your private repository and register the upstream remote:
git clone https://github.com/<your_org>/buildcage.git
cd buildcage
git remote add upstream https://github.com/buildcage/docker.git
Pulling updates
Fetch the latest changes from the original repository and merge them into your copy:
git fetch upstream --tags --force
git merge upstream/main
git push origin HEAD --tags --force
After pushing a new version tag, the Build and Push Docker Image workflow will automatically trigger and publish the updated image.
Note
If the workflow does not trigger automatically, run it manually from Actions > Build and Push Docker Image > Run workflow. The branch selection can be left as main — the workflow will build from the latest version tag.
Once the image is published, run the Update major version tag workflow to update the major/minor Docker tags (:2, :2.1) and the major git tag (v2):
- Navigate to Actions > Update major version tag
- Click Run workflow
- Enter the release tag (e.g.,
v2.1.4) - Click Run workflow