From 9d5d157f91869a1712988e9672e41665d239efb6 Mon Sep 17 00:00:00 2001 From: Andrew Stoltz Date: Sun, 17 May 2026 23:06:46 -0500 Subject: [PATCH] feat(github-runner): add final long-tail runners --- apps/github-runner/README.md | 23 +- apps/github-runner/github-runner.yaml | 2080 ++++++++++++++++++++++++- 2 files changed, 2093 insertions(+), 10 deletions(-) diff --git a/apps/github-runner/README.md b/apps/github-runner/README.md index c677c10..a7e3552 100644 --- a/apps/github-runner/README.md +++ b/apps/github-runner/README.md @@ -15,9 +15,18 @@ All repo-scoped Linux runners use: Actions tool cache `github-runner` for `FlowerCore.Common` is single-replica because it retains the -original Longhorn ReadWriteOnce NuGet PVC. `github-runner-sharedpos` and the top -Linux-cost repo runners use two replicas with per-pod `emptyDir` caches. That is -the safe backlog-drain strategy: no two pods share one RWO PVC. +original Longhorn ReadWriteOnce NuGet PVC. Every other repo-scoped runner uses +two replicas with per-pod `emptyDir` caches. That is the safe backlog-drain +strategy: no two pods share one RWO PVC. + +Sprint 32 final long-tail wave adds 16 two-replica Deployments: +`FlowerCore.Knowledge`, `FlowerCore.LlmBridge`, `FlowerCore.Media`, +`FlowerCore.Presentations`, `FlowerCore.RemoteDesktop`, `FlowerCore.DNS`, +`FlowerCore.Distribution`, `FlowerCore.Scoreboard`, +`FlowerCore.SegmentDisplay`, `FlowerCore.Signage.Contracts`, +`FlowerCore.SignalControl`, `FlowerCore.Intranet.Web`, +`FlowerCore.Provisioning`, `FlowerCore.Redis`, `FlowerCore.MessageBoard`, and +`FlowerCore.MenuBoard`. ## Post-Merge Proof @@ -32,7 +41,13 @@ Verify GitHub registration for the repo-scoped runners: ```bash for repo in FlowerCore.Common FlowerCore.Shared.Pos FlowerCore.Puppet FlowerCore.Signage \ FlowerCore.DMS FlowerCore.Telephony FlowerCore.Print.Web FlowerCore.Chat \ - FlowerCore.MySQL FlowerCore.Kiosk.Linux; do + FlowerCore.MySQL FlowerCore.Kiosk.Linux FlowerCore.Marquee FlowerCore.TtsReader \ + FlowerCore.Knowledge FlowerCore.LlmBridge FlowerCore.Media \ + FlowerCore.Presentations FlowerCore.RemoteDesktop FlowerCore.DNS \ + FlowerCore.Distribution FlowerCore.Scoreboard FlowerCore.SegmentDisplay \ + FlowerCore.Signage.Contracts FlowerCore.SignalControl FlowerCore.Intranet.Web \ + FlowerCore.Provisioning FlowerCore.Redis FlowerCore.MessageBoard \ + FlowerCore.MenuBoard; do echo "=== $repo ===" gh api "/repos/astoltz/$repo/actions/runners" \ --jq '.runners[] | select(.labels[].name == "fc-build-linux") | {name,status,busy,labels:[.labels[].name]}' diff --git a/apps/github-runner/github-runner.yaml b/apps/github-runner/github-runner.yaml index f7acdf1..957391f 100644 --- a/apps/github-runner/github-runner.yaml +++ b/apps/github-runner/github-runner.yaml @@ -11,7 +11,11 @@ # FlowerCore.Common (single replica, 5Gi Longhorn RWO NuGet PVC) # FlowerCore.Shared.Pos (two replicas, emptyDir cache) # FlowerCore.Puppet, Signage, DMS, Telephony, Print.Web, Chat, MySQL, -# Kiosk.Linux (two replicas each, emptyDir cache) +# Kiosk.Linux, Marquee, TtsReader (two replicas each, emptyDir cache) +# FlowerCore.Knowledge, LlmBridge, Media, Presentations, RemoteDesktop, +# DNS, Distribution, Scoreboard, SegmentDisplay, Signage.Contracts, +# SignalControl, Intranet.Web, Provisioning, Redis, MessageBoard, MenuBoard +# (Sprint 32 final long-tail wave; two replicas each, emptyDir cache) # # Non-root CI safety: # Runner pods run as uid 1001. HOME, DOTNET_INSTALL_DIR, DOTNET_CLI_HOME, @@ -32,7 +36,7 @@ # - Do not hardcode PATs or registration tokens. # # Designs: docs/infrastructure/self-hosted-runner-fleet.md -# ADR-172, Q-CI-26..40 +# ADR-172, Q-CI-26..40, Q-CI-86..100 --- apiVersion: v1 kind: Namespace @@ -1699,9 +1703,2073 @@ spec: emptyDir: {} restartPolicy: Always +--- +# Runner for FlowerCore.Knowledge. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-knowledge + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-knowledge + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: knowledge + flowercore.io/github-repo: FlowerCore.Knowledge +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-knowledge + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-knowledge + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: knowledge + flowercore.io/github-repo: FlowerCore.Knowledge + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Knowledge" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-knowledge" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.LlmBridge. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-llm-bridge + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-llm-bridge + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: llm-bridge + flowercore.io/github-repo: FlowerCore.LlmBridge +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-llm-bridge + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-llm-bridge + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: llm-bridge + flowercore.io/github-repo: FlowerCore.LlmBridge + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.LlmBridge" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-llm-bridge" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Media. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-media + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-media + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: media + flowercore.io/github-repo: FlowerCore.Media +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-media + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-media + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: media + flowercore.io/github-repo: FlowerCore.Media + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Media" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-media" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Presentations. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-presentations + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-presentations + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: presentations + flowercore.io/github-repo: FlowerCore.Presentations +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-presentations + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-presentations + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: presentations + flowercore.io/github-repo: FlowerCore.Presentations + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Presentations" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-presentations" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.RemoteDesktop. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-remote-desktop + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-remote-desktop + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: remote-desktop + flowercore.io/github-repo: FlowerCore.RemoteDesktop +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-remote-desktop + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-remote-desktop + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: remote-desktop + flowercore.io/github-repo: FlowerCore.RemoteDesktop + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.RemoteDesktop" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-remote-desktop" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.DNS. Added 2026-05-24 (Sprint 32 final long-tail wave). +# Mirrors the Marquee/TtsReader emptyDir pattern: two replicas, shared +# 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-dns + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-dns + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: dns + flowercore.io/github-repo: FlowerCore.DNS +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-dns + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-dns + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: dns + flowercore.io/github-repo: FlowerCore.DNS + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.DNS" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-dns" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Distribution. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-distribution + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-distribution + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: distribution + flowercore.io/github-repo: FlowerCore.Distribution +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-distribution + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-distribution + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: distribution + flowercore.io/github-repo: FlowerCore.Distribution + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Distribution" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-distribution" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Scoreboard. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-scoreboard + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-scoreboard + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: scoreboard + flowercore.io/github-repo: FlowerCore.Scoreboard +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-scoreboard + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-scoreboard + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: scoreboard + flowercore.io/github-repo: FlowerCore.Scoreboard + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Scoreboard" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-scoreboard" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.SegmentDisplay. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-segment-display + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-segment-display + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: segment-display + flowercore.io/github-repo: FlowerCore.SegmentDisplay +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-segment-display + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-segment-display + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: segment-display + flowercore.io/github-repo: FlowerCore.SegmentDisplay + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.SegmentDisplay" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-segment-display" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Signage.Contracts. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-signage-contracts + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-signage-contracts + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: signage-contracts + flowercore.io/github-repo: FlowerCore.Signage.Contracts +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-signage-contracts + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-signage-contracts + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: signage-contracts + flowercore.io/github-repo: FlowerCore.Signage.Contracts + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Signage.Contracts" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-signage-contracts" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.SignalControl. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-signal-control + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-signal-control + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: signal-control + flowercore.io/github-repo: FlowerCore.SignalControl +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-signal-control + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-signal-control + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: signal-control + flowercore.io/github-repo: FlowerCore.SignalControl + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.SignalControl" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-signal-control" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Intranet.Web. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-intranet-web + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-intranet-web + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: intranet-web + flowercore.io/github-repo: FlowerCore.Intranet.Web +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-intranet-web + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-intranet-web + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: intranet-web + flowercore.io/github-repo: FlowerCore.Intranet.Web + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Intranet.Web" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-intranet-web" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Provisioning. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-provisioning + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-provisioning + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: provisioning + flowercore.io/github-repo: FlowerCore.Provisioning +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-provisioning + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-provisioning + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: provisioning + flowercore.io/github-repo: FlowerCore.Provisioning + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Provisioning" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-provisioning" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.Redis. Added 2026-05-24 (Sprint 32 final long-tail wave). +# Mirrors the Marquee/TtsReader emptyDir pattern: two replicas, shared +# 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-redis + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-redis + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: redis + flowercore.io/github-repo: FlowerCore.Redis +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-redis + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-redis + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: redis + flowercore.io/github-repo: FlowerCore.Redis + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.Redis" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-redis" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.MessageBoard. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-message-board + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-message-board + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: message-board + flowercore.io/github-repo: FlowerCore.MessageBoard +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-message-board + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-message-board + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: message-board + flowercore.io/github-repo: FlowerCore.MessageBoard + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.MessageBoard" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-message-board" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always +--- +# Runner for FlowerCore.MenuBoard. Added 2026-05-24 (Sprint 32 final +# long-tail wave). Mirrors the Marquee/TtsReader emptyDir pattern: two +# replicas, shared 1Password-backed ACCESS_TOKEN, and the common ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: github-runner-menu-board + namespace: github-runner + labels: + app.kubernetes.io/name: github-runner-menu-board + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + app.kubernetes.io/managed-by: argocd + flowercore.io/created-by: argocd + flowercore.io/runner-repo: menu-board + flowercore.io/github-repo: FlowerCore.MenuBoard +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: github-runner-menu-board + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: github-runner-menu-board + app.kubernetes.io/component: runner + app.kubernetes.io/part-of: flowercore + flowercore.io/created-by: argocd + flowercore.io/runner-repo: menu-board + flowercore.io/github-repo: FlowerCore.MenuBoard + spec: + serviceAccountName: github-runner + securityContext: + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + initContainers: + - name: setup-runner-home + image: busybox:1.36 + command: + - sh + - -c + - | + set -e + mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet + chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget + chmod -R 755 /home/runner/.dotnet /home/runner/.nuget + securityContext: + runAsUser: 0 + runAsNonRoot: false + volumeMounts: + - name: runner-home + mountPath: /home/runner + containers: + - name: runner + image: myoung34/github-runner:latest + imagePullPolicy: Always + env: + - name: REPO_URL + value: "https://github.com/astoltz/FlowerCore.MenuBoard" + - name: RUNNER_NAME_PREFIX + value: "rke2-linux-menu-board" + - name: RUNNER_WORKDIR + value: "/tmp/runner/work" + - name: EPHEMERAL + value: "true" + - name: LABELS + value: "self-hosted,linux,fc-build-linux" + - name: HOME + value: "/home/runner" + - name: DOTNET_INSTALL_DIR + value: "/home/runner/.dotnet" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: "1" + - name: DOTNET_NOLOGO + value: "1" + - name: DOTNET_GENERATE_ASPNET_CERTIFICATE + value: "false" + - name: DOTNET_CLI_HOME + value: "/home/runner" + - name: NUGET_PACKAGES + value: "/home/runner/.nuget/packages" + - name: XDG_CACHE_HOME + value: "/home/runner/.cache" + - name: RUNNER_TOOL_CACHE + value: "/home/runner/_tool" + - name: ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: github-runner-token + key: credential + - name: RUN_AS_ROOT + value: "false" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "4Gi" + volumeMounts: + - name: runner-home + mountPath: /home/runner + - name: nuget-cache + mountPath: /home/runner/.nuget/packages + - name: tmp + mountPath: /tmp + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "pgrep -f Runner.Listener > /dev/null" + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + volumes: + - name: runner-home + emptyDir: {} + - name: nuget-cache + emptyDir: + sizeLimit: 2Gi + - name: tmp + emptyDir: {} + restartPolicy: Always + # Long-tail runner pattern: # -# Add lower-volume repos on demand with the same emptyDir runner shape above. -# Use replicas: 1 by default, replicas: 2 only when queue time proves it is -# useful. Do not create a multi-replica Deployment that shares one RWO PVC. -# Common remains the only PVC-backed runner here, and it stays replicas: 1. +# Sprint 32 added the final 16 long-tail repo-scoped Deployments above. Keep +# Common as the only PVC-backed runner at replicas: 1. Any future multi-replica +# runner must use per-pod emptyDir caches, not a shared ReadWriteOnce PVC. -- 2.49.1