feat(deploy): add scripts/build-push.sh for the Zot registry
registry.itsh.dev runs Zot, which only accepts OCI image indexes with SLSA provenance attestations. A plain 'docker build && docker push' produces a bare manifest and is rejected with 'manifest invalid' — the same gotcha documented in self-hosted/ente. The script mirrors that working pattern: buildx with --provenance mode=max, --platform linux/amd64, integrated --push. Auto-detects the default tag from cronjob.yaml so build-push and the manifest can't drift; override with TAG= when releasing a new version.
This commit is contained in:
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# build-push.sh — build the claude-matrix-bot image and push to registry.itsh.dev.
|
||||
#
|
||||
# registry.itsh.dev runs Zot, which only accepts images wrapped in an OCI image
|
||||
# index with SLSA-style provenance attestations — exactly what BuildKit produces
|
||||
# when `--provenance` is enabled. A plain `docker build && docker push` flow
|
||||
# produces a bare image manifest (no index) and Zot rejects it as
|
||||
# `manifest invalid`. Hence `--provenance mode=max` and the integrated `--push`.
|
||||
#
|
||||
# Env overrides:
|
||||
# TAG image tag (default: matches deploy/k8s/cronjob.yaml's pinned tag)
|
||||
# REGISTRY registry hostname (default: registry.itsh.dev)
|
||||
# IMAGE_REPO full repo path (default: ${REGISTRY}/vikingowl/claude-matrix-bot)
|
||||
# PLATFORM target platform (default: linux/amd64)
|
||||
#
|
||||
# Examples:
|
||||
# ./scripts/build-push.sh # build current pinned tag
|
||||
# TAG=0.2.0 ./scripts/build-push.sh # release a new version
|
||||
# TAG=$(git rev-parse --short=8 HEAD) ./scripts/build-push.sh # SHA tag
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
REGISTRY="${REGISTRY:-registry.itsh.dev}"
|
||||
IMAGE_REPO="${IMAGE_REPO:-${REGISTRY}/vikingowl/claude-matrix-bot}"
|
||||
PLATFORM="${PLATFORM:-linux/amd64}"
|
||||
|
||||
# Default TAG = whatever cronjob.yaml currently pins. Keeps build-push and the
|
||||
# manifest in sync without forcing operators to remember a magic number.
|
||||
DEFAULT_TAG="$(grep -E 'image:\s+registry\.itsh\.dev/' "${REPO_ROOT}/deploy/k8s/cronjob.yaml" \
|
||||
| sed -E 's|.*:([^:[:space:]]+)\s*$|\1|' \
|
||||
| head -n1)"
|
||||
TAG="${TAG:-${DEFAULT_TAG:-0.1.0}}"
|
||||
|
||||
IMAGE="${IMAGE_REPO}:${TAG}"
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "error: docker not installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">> Building + pushing ${IMAGE}"
|
||||
echo ">> platform=${PLATFORM} provenance=mode=max (Zot requires the OCI index wrapper)"
|
||||
|
||||
docker buildx build \
|
||||
--platform "${PLATFORM}" \
|
||||
--provenance mode=max \
|
||||
--push \
|
||||
-t "${IMAGE}" \
|
||||
"${REPO_ROOT}"
|
||||
|
||||
echo ""
|
||||
echo ">> Verifying manifest landed in registry"
|
||||
docker manifest inspect "${IMAGE}" >/dev/null
|
||||
|
||||
echo ""
|
||||
echo "Done. Image: ${IMAGE}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
if [[ "${TAG}" != "${DEFAULT_TAG}" ]]; then
|
||||
echo " 1. Bump the image tag in deploy/k8s/cronjob.yaml to :${TAG}"
|
||||
echo " (currently pinned to :${DEFAULT_TAG})"
|
||||
echo " 2. kubectl -n tenant-2 apply -k deploy/k8s"
|
||||
else
|
||||
echo " 1. kubectl -n tenant-2 apply -k deploy/k8s # already pinned to :${TAG}"
|
||||
fi
|
||||
echo " 3. kubectl -n tenant-2 create job --from=cronjob/claude-matrix-bot-reset-watcher manual-test-N"
|
||||
echo " 4. kubectl -n tenant-2 logs -f job/manual-test-N"
|
||||
Reference in New Issue
Block a user