commit 7469cf3b42db7b8209c3e25d288fe07c163da8a6 parent 98ad09b6c7270c05e9b1e75d1072904b5be4bbfb Author: MTRNord <MTRNord@users.noreply.github.com> Date: Sun, 29 Mar 2026 16:03:51 +0200 build images on ci directly Signed-off-by: MTRNord <MTRNord@users.noreply.github.com> Diffstat:
13 files changed, 677 insertions(+), 0 deletions(-)
diff --git a/apps/talos_cluster/image-builder/binfmt-daemonset.yaml b/apps/talos_cluster/image-builder/binfmt-daemonset.yaml @@ -0,0 +1,52 @@ +# Registers QEMU x86_64 binfmt_misc handler on every arm64 node so that +# buildkitd can transparently cross-compile linux/amd64 images. +# +# tonistiigi/binfmt uses the kernel "F" (fixed-binary) flag, meaning the +# QEMU binary fd is held by the kernel and persists even if this pod restarts. +# Registrations are cleared on node reboot only. +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: binfmt + namespace: image-builder +spec: + selector: + matchLabels: + app: binfmt + updateStrategy: + type: RollingUpdate + template: + metadata: + labels: + app: binfmt + spec: + # Run as quickly as possible on every node (including control-plane) + tolerations: + - operator: Exists + initContainers: + - name: binfmt-install + image: tonistiigi/binfmt:latest + args: + - --install + - qemu-x86_64 + securityContext: + privileged: true + containers: + # Pause container keeps the DaemonSet pod alive so we can track which + # nodes have had the registration applied. + - name: pause + image: alpine:3 + command: + - sleep + - infinity + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + resources: + requests: + cpu: 1m + memory: 8Mi + limits: + memory: 16Mi diff --git a/apps/talos_cluster/image-builder/build-blog-cronjob.yaml b/apps/talos_cluster/image-builder/build-blog-cronjob.yaml @@ -0,0 +1,131 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: build-blog + namespace: image-builder +spec: + schedule: "0 3 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + ttlSecondsAfterFinished: 86400 + template: + spec: + serviceAccountName: image-builder-cronjob + restartPolicy: OnFailure + initContainers: + # Stage buildctl binary from the official buildkit image + - name: setup-buildctl + image: moby/buildkit:v0.16.0 + command: [cp, /usr/bin/buildctl, /tools/buildctl] + volumeMounts: + - name: tools + mountPath: /tools + + # Stage cosign binary + - name: setup-cosign + image: gcr.io/projectsigstore/cosign:v3.0.5 + command: [cp, /ko-app/cosign, /tools/cosign] + volumeMounts: + - name: tools + mountPath: /tools + + # Stage crane binary (for re-tagging after push) + - name: setup-crane + image: gcr.io/go-containerregistry/crane:v0.20.2 + command: [cp, /ko-app/crane, /tools/crane] + volumeMounts: + - name: tools + mountPath: /tools + + # Clone the gitops repo to get the Dockerfile + - name: clone-repo + image: alpine/git:latest + command: + - git + - clone + - --depth=1 + - https://github.com/MTRNord/cluster.git + - /workspace + volumeMounts: + - name: workspace + mountPath: /workspace + + containers: + - name: build + image: alpine:3 + command: + - /bin/sh + - -c + - | + set -eu + export PATH="/tools:$PATH" + + # Registry auth for crane and cosign (buildkitd uses its own mounted config) + mkdir -p /root/.docker + cp /registry-secret/dockerconfig.json /root/.docker/config.json + + TAG_TS="$(date -u +%Y%m%d-%H%M%S)" + TAG_SHA="sha-$(git -C /workspace rev-parse --short HEAD)" + IMAGE="registry.midnightthoughts.space/mtrnord/blog" + + echo "==> Building ${IMAGE}:${TAG_TS}" + + buildctl \ + --addr tcp://buildkitd.image-builder.svc.cluster.local:1234 \ + build \ + --frontend dockerfile.v0 \ + --opt platform=linux/amd64,linux/arm64 \ + --local context=/workspace/apps/talos_cluster/blog/docker \ + --local dockerfile=/workspace/apps/talos_cluster/blog/docker \ + --output "type=image,name=${IMAGE}:${TAG_TS},push=true" \ + --metadata-file /tmp/build-meta.json + + DIGEST="$(grep -o '"containerimage.digest":"sha256:[a-f0-9]*"' /tmp/build-meta.json | head -1 | cut -d'"' -f4)" + echo "==> Digest: ${DIGEST}" + + # Add convenience tags (does not re-push layers, registry-side copy) + crane cp "${IMAGE}:${TAG_TS}" "${IMAGE}:latest" + crane cp "${IMAGE}:${TAG_TS}" "${IMAGE}:${TAG_SHA}" + + # Sign the manifest index + COSIGN_PASSWORD="$(cat /cosign-secret/cosign.password)" \ + cosign sign --yes \ + --key /cosign-secret/cosign.key \ + --new-bundle-format=false \ + --use-signing-config=false \ + --registry-referrers-mode=oci-1-1 \ + "${IMAGE}@${DIGEST}" + + echo "==> Done: ${IMAGE}:${TAG_TS}" + env: + - name: COSIGN_OCI_EXPERIMENTAL + value: "1" + - name: COSIGN_EXPERIMENTAL + value: "1" + volumeMounts: + - name: tools + mountPath: /tools + - name: workspace + mountPath: /workspace + readOnly: true + - name: registry-secret + mountPath: /registry-secret + readOnly: true + - name: cosign-secret + mountPath: /cosign-secret + readOnly: true + + volumes: + - name: tools + emptyDir: {} + - name: workspace + emptyDir: {} + - name: registry-secret + secret: + secretName: image-builder-registry-secret + - name: cosign-secret + secret: + secretName: image-builder-cosign-secret diff --git a/apps/talos_cluster/image-builder/build-bookwyrm-cronjob.yaml b/apps/talos_cluster/image-builder/build-bookwyrm-cronjob.yaml @@ -0,0 +1,198 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: build-bookwyrm + namespace: image-builder +spec: + schedule: "0 4 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + ttlSecondsAfterFinished: 86400 + template: + spec: + serviceAccountName: image-builder-cronjob + restartPolicy: OnFailure + initContainers: + # Step 1: Check upstream version and whether it already exists in registry. + # Writes the upstream version to /workspace/version. + # Writes /workspace/skip if the tag already exists (nothing to do). + - name: check-version + image: alpine:3 + command: + - /bin/sh + - -c + - | + set -eu + apk add --no-cache curl >/dev/null 2>&1 + + NEW=$(curl -sf "https://api.github.com/repos/bookwyrm-social/bookwyrm/releases/latest" \ + | grep '"tag_name"' | head -1 | cut -d'"' -f4) + + if [ -z "$NEW" ]; then + echo "ERROR: could not determine upstream version" >&2 + exit 1 + fi + + echo "Upstream version: ${NEW}" + echo "${NEW}" > /workspace/version + + TAGS=$(curl -sf "https://registry.midnightthoughts.space/v2/mtrnord/bookwyrm/tags/list" \ + | grep -o '"tags":\[[^]]*\]' || echo "") + if echo "$TAGS" | grep -q "\"${NEW}\""; then + echo "Tag ${NEW} already exists in registry — skipping build" + touch /workspace/skip + else + echo "Tag ${NEW} not found in registry — will build" + fi + volumeMounts: + - name: workspace + mountPath: /workspace + + # Step 2: Stage build tools (always runs; harmless if build is skipped) + - name: setup-buildctl + image: moby/buildkit:v0.16.0 + command: [cp, /usr/bin/buildctl, /tools/buildctl] + volumeMounts: + - name: tools + mountPath: /tools + + - name: setup-cosign + image: gcr.io/projectsigstore/cosign:v3.0.5 + command: [cp, /ko-app/cosign, /tools/cosign] + volumeMounts: + - name: tools + mountPath: /tools + + - name: setup-crane + image: gcr.io/go-containerregistry/crane:v0.20.2 + command: [cp, /ko-app/crane, /tools/crane] + volumeMounts: + - name: tools + mountPath: /tools + + # Step 3: Clone gitops repo to get the dockerfile.patch + - name: clone-gitops + image: alpine/git:latest + command: + - git + - clone + - --depth=1 + - https://github.com/MTRNord/cluster.git + - /workspace/gitops + volumeMounts: + - name: workspace + mountPath: /workspace + + # Step 4: Clone upstream bookwyrm at the detected version and apply patch. + # Skips everything if /workspace/skip exists. + - name: clone-bookwyrm + image: alpine/git:latest + command: + - /bin/sh + - -c + - | + set -eu + if [ -f /workspace/skip ]; then + echo "Skipping bookwyrm clone (tag already in registry)" + exit 0 + fi + + VERSION="$(cat /workspace/version)" + echo "Cloning bookwyrm ${VERSION}" + + git clone --depth=1 --branch "${VERSION}" \ + https://github.com/bookwyrm-social/bookwyrm.git \ + /workspace/bookwyrm + + cd /workspace/bookwyrm + + PATCH="/workspace/gitops/apps/talos_cluster/bookwyrm/dockerfile.patch" + if git apply --check "$PATCH" 2>/dev/null; then + git apply "$PATCH" + echo "Dockerfile patch applied successfully" + else + echo "Patch does not apply cleanly — upstream Dockerfile likely already includes the changes, proceeding as-is" + fi + volumeMounts: + - name: workspace + mountPath: /workspace + + containers: + - name: build + image: alpine:3 + command: + - /bin/sh + - -c + - | + set -eu + export PATH="/tools:$PATH" + + if [ -f /workspace/skip ]; then + echo "Nothing to build — tag already exists in registry" + exit 0 + fi + + VERSION="$(cat /workspace/version)" + IMAGE="registry.midnightthoughts.space/mtrnord/bookwyrm" + + mkdir -p /root/.docker + cp /registry-secret/dockerconfig.json /root/.docker/config.json + + echo "==> Building ${IMAGE}:${VERSION}" + + buildctl \ + --addr tcp://buildkitd.image-builder.svc.cluster.local:1234 \ + build \ + --frontend dockerfile.v0 \ + --opt platform=linux/amd64,linux/arm64 \ + --local context=/workspace/bookwyrm \ + --local dockerfile=/workspace/bookwyrm \ + --output "type=image,name=${IMAGE}:${VERSION},push=true" \ + --metadata-file /tmp/build-meta.json + + DIGEST="$(grep -o '"containerimage.digest":"sha256:[a-f0-9]*"' /tmp/build-meta.json | head -1 | cut -d'"' -f4)" + echo "==> Digest: ${DIGEST}" + + crane cp "${IMAGE}:${VERSION}" "${IMAGE}:latest" + + COSIGN_PASSWORD="$(cat /cosign-secret/cosign.password)" \ + cosign sign --yes \ + --key /cosign-secret/cosign.key \ + --new-bundle-format=false \ + --use-signing-config=false \ + --registry-referrers-mode=oci-1-1 \ + "${IMAGE}@${DIGEST}" + + echo "==> Done: ${IMAGE}:${VERSION}" + env: + - name: COSIGN_OCI_EXPERIMENTAL + value: "1" + - name: COSIGN_EXPERIMENTAL + value: "1" + volumeMounts: + - name: tools + mountPath: /tools + - name: workspace + mountPath: /workspace + readOnly: true + - name: registry-secret + mountPath: /registry-secret + readOnly: true + - name: cosign-secret + mountPath: /cosign-secret + readOnly: true + + volumes: + - name: tools + emptyDir: {} + - name: workspace + emptyDir: {} + - name: registry-secret + secret: + secretName: image-builder-registry-secret + - name: cosign-secret + secret: + secretName: image-builder-cosign-secret diff --git a/apps/talos_cluster/image-builder/build-continuwuity-cronjob.yaml b/apps/talos_cluster/image-builder/build-continuwuity-cronjob.yaml @@ -0,0 +1,124 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: build-continuwuity + namespace: image-builder +spec: + schedule: "0 3 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + ttlSecondsAfterFinished: 86400 + template: + spec: + serviceAccountName: image-builder-cronjob + restartPolicy: OnFailure + initContainers: + - name: setup-buildctl + image: moby/buildkit:v0.16.0 + command: [cp, /usr/bin/buildctl, /tools/buildctl] + volumeMounts: + - name: tools + mountPath: /tools + + - name: setup-cosign + image: gcr.io/projectsigstore/cosign:v3.0.5 + command: [cp, /ko-app/cosign, /tools/cosign] + volumeMounts: + - name: tools + mountPath: /tools + + - name: setup-crane + image: gcr.io/go-containerregistry/crane:v0.20.2 + command: [cp, /ko-app/crane, /tools/crane] + volumeMounts: + - name: tools + mountPath: /tools + + - name: clone-repo + image: alpine/git:latest + command: + - git + - clone + - --depth=1 + - https://github.com/MTRNord/cluster.git + - /workspace + volumeMounts: + - name: workspace + mountPath: /workspace + + containers: + - name: build + image: alpine:3 + command: + - /bin/sh + - -c + - | + set -eu + export PATH="/tools:$PATH" + + mkdir -p /root/.docker + cp /registry-secret/dockerconfig.json /root/.docker/config.json + + TAG_TS="$(date -u +%Y%m%d-%H%M%S)" + TAG_SHA="sha-$(git -C /workspace rev-parse --short HEAD)" + IMAGE="registry.midnightthoughts.space/mtrnord/cluster/continuwuity" + + echo "==> Building ${IMAGE}:${TAG_TS}" + + buildctl \ + --addr tcp://buildkitd.image-builder.svc.cluster.local:1234 \ + build \ + --frontend dockerfile.v0 \ + --opt platform=linux/amd64,linux/arm64 \ + --local context=/workspace/apps/talos_cluster/continuwuity \ + --local dockerfile=/workspace/apps/talos_cluster/continuwuity \ + --output "type=image,name=${IMAGE}:${TAG_TS},push=true" \ + --metadata-file /tmp/build-meta.json + + DIGEST="$(grep -o '"containerimage.digest":"sha256:[a-f0-9]*"' /tmp/build-meta.json | head -1 | cut -d'"' -f4)" + echo "==> Digest: ${DIGEST}" + + crane cp "${IMAGE}:${TAG_TS}" "${IMAGE}:main" + crane cp "${IMAGE}:${TAG_TS}" "${IMAGE}:${TAG_SHA}" + + COSIGN_PASSWORD="$(cat /cosign-secret/cosign.password)" \ + cosign sign --yes \ + --key /cosign-secret/cosign.key \ + --new-bundle-format=false \ + --use-signing-config=false \ + --registry-referrers-mode=oci-1-1 \ + "${IMAGE}@${DIGEST}" + + echo "==> Done: ${IMAGE}:${TAG_TS}" + env: + - name: COSIGN_OCI_EXPERIMENTAL + value: "1" + - name: COSIGN_EXPERIMENTAL + value: "1" + volumeMounts: + - name: tools + mountPath: /tools + - name: workspace + mountPath: /workspace + readOnly: true + - name: registry-secret + mountPath: /registry-secret + readOnly: true + - name: cosign-secret + mountPath: /cosign-secret + readOnly: true + + volumes: + - name: tools + emptyDir: {} + - name: workspace + emptyDir: {} + - name: registry-secret + secret: + secretName: image-builder-registry-secret + - name: cosign-secret + secret: + secretName: image-builder-cosign-secret diff --git a/apps/talos_cluster/image-builder/buildkitd-deployment.yaml b/apps/talos_cluster/image-builder/buildkitd-deployment.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: buildkitd + namespace: image-builder +spec: + replicas: 1 + selector: + matchLabels: + app: buildkitd + template: + metadata: + labels: + app: buildkitd + spec: + containers: + - name: buildkitd + # Pin to a specific version — update to latest stable as needed + image: moby/buildkit:v0.16.0 + args: + - --addr + - tcp://0.0.0.0:1234 + ports: + - containerPort: 1234 + protocol: TCP + securityContext: + privileged: true + readinessProbe: + exec: + command: + - buildctl + - --addr + - tcp://localhost:1234 + - debug + - workers + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 6 + volumeMounts: + - name: cache + mountPath: /var/lib/buildkit + - name: docker-config + mountPath: /root/.docker + readOnly: true + volumes: + - name: cache + persistentVolumeClaim: + claimName: buildkitd-cache + - name: docker-config + secret: + secretName: image-builder-registry-secret + items: + - key: dockerconfig.json + path: config.json diff --git a/apps/talos_cluster/image-builder/buildkitd-pvc.yaml b/apps/talos_cluster/image-builder/buildkitd-pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: buildkitd-cache + namespace: image-builder +spec: + accessModes: + - ReadWriteOnce + storageClassName: hcloud-volumes + resources: + requests: + storage: 20Gi diff --git a/apps/talos_cluster/image-builder/buildkitd-service.yaml b/apps/talos_cluster/image-builder/buildkitd-service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: buildkitd + namespace: image-builder +spec: + selector: + app: buildkitd + ports: + - port: 1234 + targetPort: 1234 + protocol: TCP diff --git a/apps/talos_cluster/image-builder/cosign-secret.yaml b/apps/talos_cluster/image-builder/cosign-secret.yaml @@ -0,0 +1,32 @@ +# IMPORTANT: This file must be SOPS-encrypted before committing. +# Fill in the values from the COSIGN_PRIVATE_KEY and COSIGN_PASSWORD GitHub secrets, +# then run: +# ./encrypt.sh apps/talos_cluster/image-builder/cosign-secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: image-builder-cosign-secret + namespace: image-builder +stringData: + cosign.key: ENC[AES256_GCM,data:LNBmgVTlOsbtwzGdz1PlBBz0/w8w3A1il6+8dWsWdxavxCr5waGbO5PQ9iHGHxCoZBD6+4brUdHrEFE3ohFSngSRHpKBGY3oGG0w8KvKvNOus5/GU4666WGo7x1iMcE61gn/wBpZmG0tiq6Q9Zn3q+qQXJoHBt3Ef95iUbfjUmNSb/JmICIpy8p9TZrZj1r7PyR5pTodKoejQ08oIAIy55wC1YK2YH2BQhsZD6bgKmuhZaDQRBl9Oz4PZJfqm6K1JZOp+/M0PSByuijXpHgzHzvVj3QO7DcySwB2w+R+a2Km+jl1/ZYIgfrVm0jlIMexa1UFN8ShU7xEUEXRWkW8KgQ0uc0HmubvCV5E8KqddCoZG26DqI7gV8gSCIjNK3TOh4WiBJom8VLjkZxPtGDV5FL4xz/STK8gn2dVdFexu3to8cYcFM28ruNxIw7tDnVcyybUdaIDeJqThIhoBF2qN72SZADNFpQ0siIegG4PXM1mLaZtGzC8ulkucsd1axOHXxGwrRRjQZIz+/t8uHb/SBRNt3lo5gdrAa7JjdY9RQDE+0RYpcD8RtCkhosmf6mV5HwNBWHd1uSA7Hjnpt79tMEZhsW5dPYEyUqG97tkBG5mA2+pTGzU4+9DpNylDE8kyQexMAXBhIvYo8QrJYxsKdBSp5N1CEr7BQyuNrTukukAgs3p+9y+/wq/pfOsqpniakh9MtFHypNEzboM2R762tfkF56psEH1b82k4vWEMO0c2XCg2NrFOhqooft5iXS5rCHD8Ft5L9kmhDcI/gU5UR/Mk7NDsLorclrsKNzH5BHu44L6y4+37xWwU1v4svZ7kAWtBZhQ2Yf/FNCI6YBEO+qC36krlcEz/rIABl4=,iv:sohppSbU/94g+xbwa+YYeJ37q729PAM4KpOxjLyMvJc=,tag:OMAekiulz4hvHesl1AsDdQ==,type:str] + cosign.password: "" +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmM09JRVVZejlYc0ZsMGxF + R1N6K0puVS9DWGo0UjVab0RNQTBPczhaRGgwCk9xRnI1SktnOEVvMngzZWsyYzVE + S0ZmTE5rUi9sTlVGekxCWXVvNjdHSUEKLS0tIHF1K09PaFJZTGd6eVZGSE5sdGw1 + SkVKaVVCMVQzdWJJaXQ2Njl6Uml3TncK7ciZetJlpwXkfiSoyLKKCFjVueSvoCDC + HdHafJcfzmwGM5iYtKhVL/tbbgcxAW0UhjUXkhoKvzSn4UXhmwDLKw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-29T14:03:35Z" + mac: ENC[AES256_GCM,data:Bk51kDWLEh1qvkmB/YZefO2tD20S9MmaE3kjDIrta8ueP4dFZH2ZGI6dcpRbOwr0Se2KPuIgq9IfrxEaAQ02G6vt5+3y7GnVTnZvYiy5cU9NPsbD+u9YgW1LQFA0+4i2ZOdFGWOfF5TLjpz3F3w27lC1PZMSggSW2/5TAyZqmaQ=,iv:UcwJ5qXiOE1Qu6yHYZaZr/iO5WUozXmYATC2gdTRnAk=,tag:OL6S0LNzqOh92x572r47Ag==,type:str] + pgp: [] + encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret)$ + version: 3.9.1 diff --git a/apps/talos_cluster/image-builder/kustomization.yaml b/apps/talos_cluster/image-builder/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - namespace.yaml + - rbac.yaml + - buildkitd-pvc.yaml + - buildkitd-deployment.yaml + - buildkitd-service.yaml + - binfmt-daemonset.yaml + - registry-secret.yaml + - cosign-secret.yaml + - build-blog-cronjob.yaml + - build-continuwuity-cronjob.yaml + - build-bookwyrm-cronjob.yaml diff --git a/apps/talos_cluster/image-builder/namespace.yaml b/apps/talos_cluster/image-builder/namespace.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: image-builder + labels: + # Required for buildkitd (privileged) and binfmt (privileged) pods + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/warn: privileged diff --git a/apps/talos_cluster/image-builder/rbac.yaml b/apps/talos_cluster/image-builder/rbac.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: image-builder-cronjob + namespace: image-builder diff --git a/apps/talos_cluster/image-builder/registry-secret.yaml b/apps/talos_cluster/image-builder/registry-secret.yaml @@ -0,0 +1,33 @@ +# IMPORTANT: This file must be SOPS-encrypted before committing. +# Fill in the placeholder values, then run: +# ./encrypt.sh apps/talos_cluster/image-builder/registry-secret.yaml +# +# Generate the auth value with: +# echo -n "USERNAME:PASSWORD" | base64 +apiVersion: v1 +kind: Secret +metadata: + name: image-builder-registry-secret + namespace: image-builder +stringData: + dockerconfig.json: ENC[AES256_GCM,data:npOvF06b+ByAIYCbw8h7GXAIeerlzd+RvsoCwQHnEs4BZE81O089yZqETJ9SWnoVx6/IBUqlbo2FNGki6VYFOB4mjA9fqqrP0R/WEQ7eXa+VHlwgM8Z/lNT0IKf3SCyz9Inpd4WougbgNIag4Oa+8kk+Kss4ouNcSqJiUqkcS37SEksu48xxLrcu4wzWPF0xI1t09x8JH/pnL4MRVZ+ey1IKj9gEknl0DRNxJJgjiEnD,iv:IcwMs2Jis/SmHyLcYJLe5g1MW33nLBLJGEsHQu4chZU=,tag:D4EvKMcPmu8oNbI4nCjBwQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLQzdQK21LdVZUei9rRzEx + RjUxcERVSXRPMDhBdFNHcHkxUyt1Yno5ZHc0ClVCOUxZWkwrbmdPS0VVNWJuV3M2 + ZGpjaTdZZ0xnNHN6OStlSlBSV3hYTTQKLS0tICtOZlFua2JMQ0ladXBiUXE0eWs3 + NEFBTFNaQmRwQUhOT2NXb0dpUlphdlUKCh4AjN7+pkhnPehzc8FhNCIcLurRidSO + h7nLeIgVg7391aIqSAGRDBIUmT/sNnZVMzjvSkRDCFnhoTEGrp/4PQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-29T11:16:38Z" + mac: ENC[AES256_GCM,data:MIQJG6H6cZKKPx6r/vqEfjATr9rcZC0NGSI68ZLCfJ0E1xrrbscR9ka5WLMR6stSFSdJcvD5vXbWdsfXnL7lg7scg26f0ZwnoYr3sQEifNnLHjvh+K+2np6kmTg1m+SqbEWherVd6x818tKItVNPySY1XRO+G3uEFYoO7QMNDjM=,iv:yh8mKWpHYjZ/pmiUvm6m7j+YgdgTG/FzRd42VMTxTp8=,tag:hUXS4+FVd0uoUjXoWAoHyQ==,type:str] + pgp: [] + encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret)$ + version: 3.9.1 diff --git a/apps/talos_cluster/kustomization.yaml b/apps/talos_cluster/kustomization.yaml @@ -40,5 +40,6 @@ resources: - ./k6-operator - ./stalwart - ./zot + - ./image-builder - ./image-policies #- ./proxmox-ccm