ci(romhacks): build orchestrator image to the self-hosted registry
Build romhacks orchestrator image / build-and-push (push) Successful in 2m1s
Build romhacks orchestrator image / build-and-push (push) Successful in 2m1s
Portainer's git auto-update only runs `docker compose pull`, never `build`,
so the orchestrator's `build:` context + local-only
`homelab/romhacks-orchestrator:latest` deadlocked stack 28: every 5-min poll
died on "pull access denied" and the stack sat frozen at 847edff since
2026-06-24 while every other stack moved on.
Build it in CI and push it to registry.ginnoir.com instead, same shape as
famapp's release.yml. Compose switches to the registry image in the next
commit, once the image actually exists.
Push creds come from the committed .env rather than Gitea Actions secrets
(famapp needs those only because its repo doesn't commit .env) — one source
of truth on rotation. Only the two REGISTRY_PUSH_* keys are extracted; the
vault material in that file stays out of the job env.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
21033300bc
commit
60121a5d52
1 file changed
+99
@@ -0,0 +1,99 @@
|
||||
name: Build romhacks orchestrator image
|
||||
|
||||
# The romhacks orchestrator is the one stack service whose image is built from
|
||||
# source in THIS repo. Portainer's git auto-update only ever runs
|
||||
# `docker compose pull` — never `build` — so a compose `build:` context plus a
|
||||
# local-only `image:` name deadlocks the stack: every poll fails with
|
||||
# "pull access denied for homelab/romhacks-orchestrator" and the stack freezes
|
||||
# at whatever commit last deployed.
|
||||
#
|
||||
# So the image is built here and pushed to the self-hosted registry, exactly
|
||||
# like famapp (ginnoir/famapp .gitea/workflows/release.yml). Compose then just
|
||||
# pulls a real image like every other service.
|
||||
#
|
||||
# Triggered by any change under stacks/romhacks/orchestrator/ (scripts,
|
||||
# channels.json, Dockerfile). Editing channels.json => push => new :latest.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- stacks/romhacks/orchestrator/**
|
||||
- .gitea/workflows/build-romhacks-orchestrator.yml
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: build-romhacks-orchestrator
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Ensure docker CLI + buildx
|
||||
run: |
|
||||
# Debian's docker.io package ships no buildx plugin, which the
|
||||
# registry-cache build below requires. Install Docker's official
|
||||
# CLI + buildx plugin so the build works regardless of what the
|
||||
# runner image happens to provide.
|
||||
if docker buildx version >/dev/null 2>&1; then
|
||||
echo "docker + buildx already available"
|
||||
docker version
|
||||
docker buildx version
|
||||
exit 0
|
||||
fi
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq ca-certificates curl gnupg
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
|
||||
chmod a+r /etc/apt/keyrings/docker.asc
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
||||
> /etc/apt/sources.list.d/docker.list
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq docker-ce-cli docker-buildx-plugin
|
||||
docker version
|
||||
docker buildx version
|
||||
|
||||
- name: Login to registry
|
||||
run: |
|
||||
# Unlike famapp (separate repo, .env not committed => Gitea Actions
|
||||
# secrets), this repo commits .env on purpose, so REGISTRY_PUSH_* is
|
||||
# already in the checkout. One source of truth on rotation, no
|
||||
# out-of-band repo secrets to drift.
|
||||
# Pull ONLY these two keys rather than sourcing .env wholesale — that
|
||||
# file also carries the vault unseal keys/root token, which have no
|
||||
# business in this job's environment. Piped to --password-stdin, so
|
||||
# the value is never echoed, never in argv, never in the job log.
|
||||
eval "$(grep -E '^REGISTRY_PUSH_(USERNAME|PASSWORD)=' ./.env | sed 's/^/export /')"
|
||||
if [ -z "${REGISTRY_PUSH_USERNAME:-}" ] || [ -z "${REGISTRY_PUSH_PASSWORD:-}" ]; then
|
||||
echo "REGISTRY_PUSH_USERNAME/PASSWORD missing from .env" >&2
|
||||
exit 1
|
||||
fi
|
||||
printf '%s' "$REGISTRY_PUSH_PASSWORD" | docker login registry.ginnoir.com \
|
||||
--username "$REGISTRY_PUSH_USERNAME" \
|
||||
--password-stdin
|
||||
|
||||
- name: Set up buildx
|
||||
run: |
|
||||
docker buildx create --name romhacks-builder --use 2>/dev/null || docker buildx use romhacks-builder
|
||||
docker buildx inspect --bootstrap
|
||||
|
||||
- name: Build and push image
|
||||
env:
|
||||
IMAGE: registry.ginnoir.com/ginnoir/romhacks-orchestrator
|
||||
CACHE: registry.ginnoir.com/ginnoir/romhacks-orchestrator:buildcache
|
||||
run: |
|
||||
# No v* tags in this repo (it holds ~50 stacks, not one app), so the
|
||||
# immutable tag is the commit sha; compose tracks :latest.
|
||||
SHA_TAG="sha-$(printf '%s' "$GITHUB_SHA" | cut -c1-7)"
|
||||
docker buildx build \
|
||||
--push \
|
||||
--tag "${IMAGE}:latest" \
|
||||
--tag "${IMAGE}:${SHA_TAG}" \
|
||||
--cache-from "type=registry,ref=${CACHE}" \
|
||||
--cache-to "type=registry,ref=${CACHE},mode=max" \
|
||||
stacks/romhacks/orchestrator
|
||||
Reference in new issue
Block a user