Shape: Container Image
A container image ships as a versioned OCI artifact to a registry -- Docker Hub, GHCR (GitHub Container Registry), Amazon ECR, Google Artifact Registry, Azure Container Registry. Downstream consumers pull by tag. The release surface is a tag push to the registry.
When this shape applies
- You build a Docker / OCI image others run (not a service you deploy yourself).
- You want a versioned tag pushed to a registry on every release.
- Optionally, the same image is later deployed by a consumer's
/gaia-deploy-- but THIS project's release is the registry push, not the deployment.
project-config.yaml
environments:
- id: registry
kind: distribution-only
distribution:
channel: container-registry
registry: ghcr.io/myorg
manifest: Dockerfile
release_workflow: gaia-release.yml
image_name: myorg/myapp
tag_strategy: semver
The container-registry channel requires image_name and
tag_strategy as per-channel sub-fields. Missing either is
rejected by /gaia-config-validate.
For Docker Hub, swap the registry: registry: docker.io/myorg. For
ECR / GAR / ACR, swap to the cloud's registry hostname.
Tag strategy
semver-- the tag matches the SemVer in your release pipeline (e.g.,1.4.2). Most common; clean rollback story.sha-- the tag matches the git commit SHA (e.g.,abc1234). Useful when every build is an artifact; pairs well with GitOps consumers.latest-- the tag is the literal stringlatest, updated on every release. Discouraged for production but common for development streams.
Phase 5 routing
With kind: distribution-only + distribution:, the Phase 5 router
emits publish-primary and suggests /gaia-publish.
/gaia-deploy refuses (a container image is not a deployed service from THIS
project's perspective; consumers deploy it themselves).
Publish to Docker Hub / GHCR
/gaia-publish
The orchestrator dispatches publish-container-registry, which invokes the
configured release_workflow (typically a workflow that runs
docker buildx build --push -t $REGISTRY/$IMAGE_NAME:$TAG). The adapter
resolves the tag from tag_strategy:
semver-> reads from your manifest (e.g.,VERSIONfile orpackage.jsonversion) and pushes that exact tag.sha-> uses${GITHUB_SHA:0:7}for short SHA or the full hash.latest-> pushes the literallatesttag.
Credentials are read from the environment (REGISTRY_USER +
REGISTRY_PASSWORD for Docker Hub, GITHUB_TOKEN for GHCR). See
the per-channel adapter schema at
plugins/gaia/scripts/adapters/publish-container-registry/schema.yaml for the
full sub-field contract.
You'll know it worked when
/gaia-config-validateexits 0 withimage_name+tag_strategyboth present./gaia-helpsuggests/gaia-publishon the Phase 5 row.- A
/gaia-publishrun pushes the image;docker pull $REGISTRY/$IMAGE_NAME:$TAGsucceeds from a clean machine. - The registry web UI shows the new tag with the expected manifest digest.