recruiter-responder: pull image from ghcr + ghcr-credentials on all consumers (ADR-0002, infra#27)
All checks were successful
ci/woodpecker/push/build-cli Pipeline was successful
ci/woodpecker/push/default Pipeline was successful

Migrating recruiter-responder off in-cluster Woodpecker builds: GHA will
build and push ghcr.io/viktorbarzin/recruiter-responder (PRIVATE package).
This commit lands the pull-side prerequisites BEFORE the first off-infra
build fires:

- stacks/recruiter-responder: image base forgejo -> ghcr (inert on the live
  Deployment - both containers are ignore_changes'd; the Woodpecker deploy
  moves the tag) + ghcr-credentials imagePullSecrets on the Deployment
  (covers the recruiter-responder container AND the alembic-migrate init
  container, which share the image).
- stacks/openclaw: ghcr-credentials imagePullSecrets on the openclaw
  Deployment - its install-recruiter-plugin init container consumes the
  :latest tag of this image. The image ref itself flips to ghcr in a
  follow-up once the first GHA build has created the package (flipping now
  would ImagePullBackOff on a not-yet-existing package and wedge the apply).
- stacks/kyverno: allowlist openclaw in sync-ghcr-credentials so the pull
  secret is cloned into that namespace too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Viktor Barzin 2026-06-13 00:43:25 +00:00
parent c594274c83
commit 57ff41e47e
3 changed files with 24 additions and 3 deletions

View file

@ -24,6 +24,9 @@ locals {
"wealthfolio",
"fire-planner",
"recruiter-responder",
# openclaw's install-recruiter-plugin init container pulls the PRIVATE
# ghcr.io/viktorbarzin/recruiter-responder:latest image (infra#27).
"openclaw",
]
}

View file

@ -429,6 +429,15 @@ resource "kubernetes_deployment" "openclaw" {
spec {
service_account_name = kubernetes_service_account.openclaw.metadata[0].name
# GHCR pull secret for the install-recruiter-plugin init container
# ghcr.io/viktorbarzin/recruiter-responder is a PRIVATE package
# (ADR-0002, infra#27). Cloned into this namespace by the kyverno
# stack's sync-ghcr-credentials ClusterPolicy (openclaw allowlisted).
# Forgejo-registry images in this pod keep pulling anonymously.
image_pull_secrets {
name = "ghcr-credentials"
}
# Init 0: fix /workspace ownership so node user can write
init_container {
name = "fix-workspace-perms"
@ -541,7 +550,7 @@ resource "kubernetes_deployment" "openclaw" {
# IfNotPresent: a cached stale :latest meant the plugin manifest
# (configSchema fix) never got pulled. An uncached SHA forces the
# pull. Bump this when the openclaw plugin in nextcloud-todos changes.
image = "forgejo.viktorbarzin.me/viktor/nextcloud-todos:f85c6de1"
image = "forgejo.viktorbarzin.me/viktor/nextcloud-todos:f85c6de1"
image_pull_policy = "Always"
command = ["sh", "-c", <<-EOT
set -eu
@ -1151,7 +1160,7 @@ resource "kubernetes_deployment" "openclaw" {
# Main container: OpenClaw
container {
name = "openclaw"
name = "openclaw"
# Pinned back to 2026.2.26 (2026-06-04): 2026.5.4's gateway writes a
# model `agentRuntime` key for the openai-codex provider that it then
# rejects on startup ("Invalid config ... Unrecognized key:

View file

@ -13,7 +13,10 @@ variable "tls_secret_name" {
locals {
namespace = "recruiter-responder"
image = "forgejo.viktorbarzin.me/viktor/recruiter-responder:${var.image_tag}"
# GHA builds + pushes ghcr.io/viktorbarzin/recruiter-responder (PRIVATE,
# ADR-0002 off-infra builds, infra#27). Canonical repo stays on Forgejo;
# the GitHub mirror runs the build and the Woodpecker deploy moves the tag.
image = "ghcr.io/viktorbarzin/recruiter-responder:${var.image_tag}"
labels = {
app = "recruiter-responder"
}
@ -175,6 +178,12 @@ resource "kubernetes_deployment" "recruiter_responder" {
image_pull_secrets {
name = "registry-credentials"
}
# GHCR pull secret: the ghcr-credentials Secret in this namespace is
# cloned in by the kyverno stack's sync-ghcr-credentials ClusterPolicy
# (allowlisted namespace) the ghcr package is PRIVATE (ADR-0002).
image_pull_secrets {
name = "ghcr-credentials"
}
init_container {
name = "alembic-migrate"