# GitHub Actions self-hosted Linux runner fleet - RKE2 deployment # # ArgoCD owns this namespace. Update this manifest and let the # bluejay-infra ApplicationSet reconcile it. # # astoltz is a GitHub user account, not an org, so runners are repo-scoped. # Each Deployment registers one private FlowerCore repo with the shared # ACCESS_TOKEN from the github-runner-token Secret. # # Runners registered here: # 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, 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, # NUGET_PACKAGES, XDG_CACHE_HOME, and RUNNER_TOOL_CACHE are all pointed at # writable mounted paths under /home/runner so actions/setup-dotnet does not # attempt to install into /usr/share/dotnet. # Ruby 3.3.11 is baked into localhost/fc-github-runner:v20260525-ruby3.3.11-stepca # under /opt/runner-toolcache; setup-runner-home copies it into # /home/runner/_tool because the runner-home emptyDir masks image content # under /home/runner at runtime. # # Credentials: # OnePasswordItem "GitHub PAT (Runner Registration)" syncs Secret # github-runner-token with field "credential". The custom image inherits # myoung34/github-runner behavior and uses ACCESS_TOKEN to mint short-lived # registration tokens on pod start. # # Security model: # - No ClusterRole / ClusterRoleBinding. The ServiceAccount has no K8s API # privileges. # - Self-hosted runners are for private repos and trusted branches only. # - Fork pull-request approval must remain required in GitHub repo settings. # - Do not hardcode PATs or registration tokens. # # Designs: docs/infrastructure/self-hosted-runner-fleet.md # ADR-172, Q-CI-26..40, Q-CI-86..100 --- apiVersion: v1 kind: Namespace metadata: name: github-runner labels: app.kubernetes.io/part-of: flowercore app.kubernetes.io/managed-by: argocd --- # 1Password secret sync — creates github-runner-token K8s Secret. # Fields expected in the 1Password item: # credential — GitHub fine-grained PAT (Administration:read/write on # target repos) used by the runner image to mint a fresh # short-lived registration token at pod start. # Item path: IAmWorkin vault > "GitHub PAT (Runner Registration)" # Operator MUST create this item before the Deployment will start cleanly. apiVersion: onepassword.com/v1 kind: OnePasswordItem metadata: name: github-runner-token namespace: github-runner labels: app.kubernetes.io/component: credentials app.kubernetes.io/part-of: flowercore spec: itemPath: vaults/IAmWorkin/items/GitHub PAT (Runner Registration) --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: ServiceAccount metadata: name: github-runner namespace: github-runner labels: app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore # No ClusterRole or ClusterRoleBinding — runner has zero K8s API privileges. # CI jobs that need kubectl must supply their own kubeconfig via a secret # injected at the job level, not via this service account. --- apiVersion: apps/v1 kind: Deployment metadata: name: github-runner namespace: github-runner labels: app.kubernetes.io/name: github-runner 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: common flowercore.io/github-repo: FlowerCore.Common spec: # Single replica enforced: the Longhorn RWO PVC can only be mounted by # one pod at a time. Each pod re-registers as an ephemeral runner after # completing a job (EPHEMERAL=true restarts the container, not the pod, # so the PVC stays attached between jobs). # # 2026-05-16: bumped 0 -> 1 after operator provisioned the # "GitHub PAT (Runner Registration)" 1P item with field=credential. # Unblocks CI fleet-wide (was budget-exhausted on GH-hosted runners). replicas: 1 selector: matchLabels: app.kubernetes.io/name: github-runner # Use Recreate to avoid the Multi-Attach RWO error during rollouts. strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: common flowercore.io/github-repo: FlowerCore.Common spec: serviceAccountName: github-runner # Pin to rke2-server so the Longhorn RWO volume is always on the same node. nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 # Sprint 30 Cl-1 pod-env fix (2026-05-21): pre-create + chown # /home/runner/.dotnet + /home/runner/.nuget so the non-root runner # (UID 1001) can host setup-dotnet@v4 + dotnet restore writes without # the per-workflow DOTNET_INSTALL_DIR patch ~25 flipped Linux repos # have been carrying. Runs as root so chown succeeds; the main # container then runs as 1001 against an emptyDir mounted at # /home/runner. The PVC mount at /home/runner/.nuget/packages # (Common runner) still wins at its nested path because Kubernetes # honors the deeper mount. initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: # GitHub org/repo targeting. # Set REPO_URL for a repo-scoped runner (cheaper, simpler). # Switch to ORG_NAME + empty REPO_URL for an org-scoped runner. - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Common" - name: RUNNER_NAME_PREFIX value: "rke2-linux" - name: RUNNER_WORKDIR value: "/tmp/runner/work" # EPHEMERAL=true: runner deregisters after one job; container # exits with code 0; Deployment controller restarts it and a # fresh registration occurs. Prevents stale runner accumulation. - name: EPHEMERAL value: "true" # Labels used by workflow files: runs-on: [self-hosted, linux, fc-build-linux] - 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_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" # PAT (not pre-minted registration token) — myoung34/github-runner # mints registration tokens itself via GitHub API when ACCESS_TOKEN # is set. The 1P "GitHub PAT (Runner Registration)" item stores a # fine-grained PAT, not a short-lived registration token. - name: ACCESS_TOKEN valueFrom: secretKeyRef: name: github-runner-token key: credential # myoung34/github-runner default entrypoint expects root for some # setup steps. With securityContext.runAsUser=1001 the entrypoint # short-circuits with "RUN_AS_ROOT env var is set to true but the # user has been overridden and is not running as root". Tell the # entrypoint we're explicitly NOT root so it skips the root-only # setup steps (cache prewarm + apt updates — both already baked). - name: RUN_AS_ROOT value: "false" # Sprint 30 Cl-1 pod-env fix (2026-05-21): retire the per-workflow # DOTNET_INSTALL_DIR patch by setting siblings here so ALL flipped # Linux repos pick them up automatically. setup-dotnet@v4 default # writes to /usr/share/dotnet (root-only) or HOME-relative ~/.dotnet # without HOME guard; the DOTNET_INSTALL_DIR + NUGET_PACKAGES pins # above already point at the chowned emptyDir at /home/runner. - name: DOTNET_CLI_TELEMETRY_OPTOUT value: "1" - name: DOTNET_NOLOGO value: "1" - name: DOTNET_GENERATE_ASPNET_CERTIFICATE value: "false" resources: requests: cpu: "500m" memory: "1Gi" limits: cpu: "2000m" memory: "4Gi" volumeMounts: # /home/runner emptyDir — owned by the non-root runner thanks # to the setup-runner-home initContainer chown. Hosts .dotnet # (setup-dotnet@v4 target) and provides a writable HOME without # forcing a PVC. The PVC mount below at .nuget/packages wins # at that nested path (deeper mount overrides), so the Common # NuGet cache continues to persist across ephemeral pod restarts. - name: runner-home mountPath: /home/runner - name: nuget-cache mountPath: /home/runner/.nuget/packages - name: tmp mountPath: /tmp # Liveness: runner process is alive. 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 persistentVolumeClaim: claimName: github-runner-nuget-cache - name: tmp emptyDir: {} # Restart policy: Always — the Deployment controller handles # re-registration after each ephemeral job completes. restartPolicy: Always --- # Shared.Pos repo-scoped Linux runner. Added 2026-05-20 to unstick the # FlowerCore.Shared.Pos "Build, Test & Publish" workflow, which had been # queued indefinitely after the Sprint 26 Mac POS Phase 1/2 PRs merged # (no fc-build-linux runner was registered to Shared.Pos — GitHub user # accounts have only repo-scoped runners). First concrete instance of the # Sprint 29 Cx-1 Linux-runner-fleet pattern; the full per-repo fleet is # codified by that lane. It uses emptyDir cache and two replicas so backlog # drains without a shared RWO PVC multi-attach risk. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-sharedpos namespace: github-runner labels: app.kubernetes.io/name: github-runner-sharedpos 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: sharedpos flowercore.io/github-repo: FlowerCore.Shared.Pos spec: # UN-PARKED 2026-05-21: Shared.Pos #5 fixed the non-root setup-dotnet path # (DOTNET_INSTALL_DIR step-scoped). Sprint 30 Cl-8 capacity Q-CI-52: raised # to replicas: 2 to absorb top-8 burst load per substrate-recommended default. replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-sharedpos strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-sharedpos app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: sharedpos flowercore.io/github-repo: FlowerCore.Shared.Pos spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 # Sprint 30 Cl-1 pod-env fix (2026-05-21): see github-runner Deployment # above for full rationale. Mirrored on the Shared.Pos runner so the # per-workflow DOTNET_INSTALL_DIR patch can be retired fleet-wide # rather than re-applied per repo as flipped lanes land. initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Shared.Pos" - name: RUNNER_NAME_PREFIX value: "rke2-linux-sharedpos" - 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_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" # Sprint 30 Cl-1 pod-env fix (2026-05-21): retire per-workflow patch. # DOTNET_INSTALL_DIR + NUGET_PACKAGES already pinned above. - name: DOTNET_CLI_TELEMETRY_OPTOUT value: "1" - name: DOTNET_NOLOGO value: "1" - name: DOTNET_GENERATE_ASPNET_CERTIFICATE value: "false" resources: requests: cpu: "500m" memory: "1Gi" limits: cpu: "2000m" memory: "4Gi" volumeMounts: # Shared.Pos runner uses emptyDir for nuget cache (no node pin # via RWO PVC). /home/runner emptyDir hosts .dotnet via the # setup-runner-home initContainer chown; the .nuget/packages # emptyDir mount still wins at its nested path. - 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.Puppet. Two replicas use per-pod emptyDir caches, so # backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-puppet namespace: github-runner labels: app.kubernetes.io/name: github-runner-puppet 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: puppet flowercore.io/github-repo: FlowerCore.Puppet spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-puppet strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-puppet app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: puppet flowercore.io/github-repo: FlowerCore.Puppet spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Puppet" - name: RUNNER_NAME_PREFIX value: "rke2-linux-puppet" - 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. Two replicas use per-pod emptyDir caches, so # backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-signage namespace: github-runner labels: app.kubernetes.io/name: github-runner-signage 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 flowercore.io/github-repo: FlowerCore.Signage spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-signage strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-signage app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: signage flowercore.io/github-repo: FlowerCore.Signage spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Signage" - name: RUNNER_NAME_PREFIX value: "rke2-linux-signage" - 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.DMS. Two replicas use per-pod emptyDir caches, so # backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-dms namespace: github-runner labels: app.kubernetes.io/name: github-runner-dms 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: dms flowercore.io/github-repo: FlowerCore.DMS spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-dms strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-dms app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: dms flowercore.io/github-repo: FlowerCore.DMS spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.DMS" - name: RUNNER_NAME_PREFIX value: "rke2-linux-dms" - 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.Telephony. Two replicas use per-pod emptyDir caches, # so backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-telephony namespace: github-runner labels: app.kubernetes.io/name: github-runner-telephony 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: telephony flowercore.io/github-repo: FlowerCore.Telephony spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-telephony strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-telephony app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: telephony flowercore.io/github-repo: FlowerCore.Telephony spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Telephony" - name: RUNNER_NAME_PREFIX value: "rke2-linux-telephony" - 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.Print.Web. Two replicas use per-pod emptyDir caches, # so backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-print-web namespace: github-runner labels: app.kubernetes.io/name: github-runner-print-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: print-web flowercore.io/github-repo: FlowerCore.Print.Web spec: # Sprint 33 morning-routine (2026-05-25): bumped 2 → 3 because help-screenshots # AAT job holds a runner 30+ min, causing head-of-line blocking on parallel PRs. # 12 runs in trailing 5d. replicas: 3 selector: matchLabels: app.kubernetes.io/name: github-runner-print-web strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-print-web app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: print-web flowercore.io/github-repo: FlowerCore.Print.Web spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Print.Web" - name: RUNNER_NAME_PREFIX value: "rke2-linux-print-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.Chat. Two replicas use per-pod emptyDir caches, so # backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-chat namespace: github-runner labels: app.kubernetes.io/name: github-runner-chat 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: chat flowercore.io/github-repo: FlowerCore.Chat spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-chat strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-chat app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: chat flowercore.io/github-repo: FlowerCore.Chat spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Chat" - name: RUNNER_NAME_PREFIX value: "rke2-linux-chat" - 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.MySQL. Two replicas use per-pod emptyDir caches, so # backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-mysql namespace: github-runner labels: app.kubernetes.io/name: github-runner-mysql 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: mysql flowercore.io/github-repo: FlowerCore.MySQL spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-mysql strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-mysql app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: mysql flowercore.io/github-repo: FlowerCore.MySQL spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.MySQL" - name: RUNNER_NAME_PREFIX value: "rke2-linux-mysql" - 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.Kiosk.Linux. Two replicas use per-pod emptyDir caches, # so backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-kiosk-linux namespace: github-runner labels: app.kubernetes.io/name: github-runner-kiosk-linux 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: kiosk-linux flowercore.io/github-repo: FlowerCore.Kiosk.Linux spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-kiosk-linux strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-kiosk-linux app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: kiosk-linux flowercore.io/github-repo: FlowerCore.Kiosk.Linux spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Kiosk.Linux" - name: RUNNER_NAME_PREFIX value: "rke2-linux-kiosk-linux" - 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.Marquee. Added 2026-05-21 (Sprint 30 add-on) to drain # the 1.2.0 version-scheme alignment PR #7 publish queue. Mirrors the Sprint 29 # Cx-1 per-repo Deployment pattern (PR #5) verbatim. Two replicas use per-pod # emptyDir caches, so backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-marquee namespace: github-runner labels: app.kubernetes.io/name: github-runner-marquee 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: marquee flowercore.io/github-repo: FlowerCore.Marquee spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-marquee strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-marquee app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: marquee flowercore.io/github-repo: FlowerCore.Marquee spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Marquee" - name: RUNNER_NAME_PREFIX value: "rke2-linux-marquee" - 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.TtsReader. Added 2026-05-21 (Sprint 30 add-on) to drain # the audio 404 FcAlert surface PR #18 CI queue. Mirrors the Sprint 29 Cx-1 # per-repo Deployment pattern (PR #5) verbatim. Two replicas use per-pod # emptyDir caches, so backlog can drain without sharing a ReadWriteOnce PVC. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-tts-reader namespace: github-runner labels: app.kubernetes.io/name: github-runner-tts-reader 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: tts-reader flowercore.io/github-repo: FlowerCore.TtsReader spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-tts-reader strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-tts-reader app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: tts-reader flowercore.io/github-repo: FlowerCore.TtsReader spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.TtsReader" - name: RUNNER_NAME_PREFIX value: "rke2-linux-tts-reader" - 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" # Bumped 2026-05-25: previous 4Gi limit caused OOMKill (exit 137) # mid-`dotnet test` on TtsReader's 1000+ test suite. PR #21 CI flapped # twice with "runner lost communication" before the K8s side # symptoms surfaced. 8Gi gives ~30% headroom over peak observed. resources: requests: cpu: "500m" memory: "2Gi" limits: cpu: "2000m" memory: "8Gi" 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.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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — zero CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — zero CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — zero CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — only 6 CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — zero CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — zero CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — only 3 CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — only 3 CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — only 3 CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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: # Sprint 33 morning-routine (2026-05-25): dropped 2 → 1 — only 3 CI runs in trailing 14d. replicas: 1 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: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never 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 --- # Runner for FlowerCore.PiManager. Two replicas use per-pod emptyDir caches, so # backlog can drain without sharing a ReadWriteOnce PVC. Added 2026-05-25 to # close the runner-fleet gap that left run 26417714843 queued for 5h. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-pimanager namespace: github-runner labels: app.kubernetes.io/name: github-runner-pimanager 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: pimanager flowercore.io/github-repo: FlowerCore.PiManager spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-pimanager strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-pimanager app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: pimanager flowercore.io/github-repo: FlowerCore.PiManager spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.PiManager" - name: RUNNER_NAME_PREFIX value: "rke2-linux-pimanager" - 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.Updater. Two replicas use per-pod emptyDir caches, so # backlog can drain without sharing a ReadWriteOnce PVC. Added 2026-05-26 to # close the runner-fleet gap that left the repo with only the offline # windows-sandbox runner and no Linux PR-CI capacity for future workflows. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-updater namespace: github-runner labels: app.kubernetes.io/name: github-runner-updater 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: updater flowercore.io/github-repo: FlowerCore.Updater spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-updater strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-updater app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: updater flowercore.io/github-repo: FlowerCore.Updater spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Updater" - name: RUNNER_NAME_PREFIX value: "rke2-linux-updater" - 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.DeviceManagement. Two replicas use per-pod emptyDir # caches, so backlog can drain without sharing a ReadWriteOnce PVC. Added # 2026-05-26 morning-routine — DM had ZERO registered runners while Sprint 37 # Cx-1 PRs #20 (CI-to-Linux migration), #21 (WDAC), and #22 (AppLocker) were # all queued indefinitely. Chicken-and-egg: the migration PRs need Linux # runners that the migration creates. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-device-management namespace: github-runner labels: app.kubernetes.io/name: github-runner-device-management 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: device-management flowercore.io/github-repo: FlowerCore.DeviceManagement spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-device-management strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-device-management app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: device-management flowercore.io/github-repo: FlowerCore.DeviceManagement spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.DeviceManagement" - name: RUNNER_NAME_PREFIX value: "rke2-linux-device-management" - 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: # Reduced from 500m → 100m 2026-05-26 because cluster CPU # requests were at 99% across all 3 nodes; idle runners use ~1m. # Burst headroom preserved by limits.cpu: 2000m. requests: cpu: "100m" 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.AiStation.Linux. Two replicas use per-pod emptyDir # caches. Added 2026-05-26 — #13 master-CI-fix PR was queued indefinitely # (Linux job has no runner; Windows job remains queued until the Windows # runner host substrate lands per Sprint 36 v2 Cl-2 / ADR-174). apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-aistation-linux namespace: github-runner labels: app.kubernetes.io/name: github-runner-aistation-linux 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: aistation-linux flowercore.io/github-repo: FlowerCore.AiStation.Linux spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-aistation-linux strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-aistation-linux app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: aistation-linux flowercore.io/github-repo: FlowerCore.AiStation.Linux spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.AiStation.Linux" - name: RUNNER_NAME_PREFIX value: "rke2-linux-aistation-linux" - 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: "100m" 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.WorldBuilder. Two replicas use per-pod emptyDir # caches. Added 2026-05-26 — #3 and #4 Linux migration PRs queued # indefinitely with one stale offline runner registered against the repo. apiVersion: apps/v1 kind: Deployment metadata: name: github-runner-worldbuilder namespace: github-runner labels: app.kubernetes.io/name: github-runner-worldbuilder 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: worldbuilder flowercore.io/github-repo: FlowerCore.WorldBuilder spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: github-runner-worldbuilder strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: github-runner-worldbuilder app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore flowercore.io/created-by: argocd flowercore.io/runner-repo: worldbuilder flowercore.io/github-repo: FlowerCore.WorldBuilder spec: serviceAccountName: github-runner securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 initContainers: - name: setup-runner-home image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never command: - sh - -c - | set -e mkdir -p /home/runner/.dotnet /home/runner/.nuget/packages /home/runner/.nuget/NuGet /home/runner/.cache /home/runner/_tool if [ -d /opt/runner-toolcache/Ruby ] && [ ! -d /home/runner/_tool/Ruby ]; then cp -a /opt/runner-toolcache/Ruby /home/runner/_tool/ fi chown -R 1001:1001 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool chmod -R 755 /home/runner/.dotnet /home/runner/.nuget /home/runner/.cache /home/runner/_tool securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: runner-home mountPath: /home/runner containers: - name: runner image: localhost/fc-github-runner:v20260525-ruby3.3.11-stepca imagePullPolicy: Never env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.WorldBuilder" - name: RUNNER_NAME_PREFIX value: "rke2-linux-worldbuilder" - 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: "100m" 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: # # 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. # 2026-05-25: PiManager added (was missed in the Sprint 32 long-tail sweep). # 2026-05-26: Updater + DeviceManagement + AiStation.Linux + WorldBuilder # added by the morning-routine sweep — those repos had had ZERO online Linux # PR-CI capacity, blocking the Sprint 37 Cx-1 Linux-CI-migration PRs.