# GitHub Actions self-hosted Linux runner fleet # # ArgoCD owns this namespace. Do not kubectl-apply ad hoc runner changes over # it; update this manifest and let the bluejay-infra ApplicationSet reconcile. # # astoltz is a GitHub user account, not an org, so runners must be repo-scoped. # Each Deployment below registers exactly one ephemeral myoung34/github-runner # instance against one private FlowerCore repo using the shared PAT from the # github-runner-token Secret. # # Current shape: # - Common runner preserved from the phase-2 pilot. # - Sprint 29 top-8 Linux-cost repos added first: # Puppet, Signage, DMS, Telephony, Print.Web, Chat, MySQL, Kiosk.Linux. # # Security: # - No ClusterRole / ClusterRoleBinding. # - 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. --- 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 with Administration:read/write on # each target repo. myoung34/github-runner uses ACCESS_TOKEN to # mint fresh short-lived registration tokens at pod startup. # Item path: IAmWorkin vault > "GitHub PAT (Runner Registration)" 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: ServiceAccount metadata: name: github-runner namespace: github-runner labels: app.kubernetes.io/component: runner app.kubernetes.io/part-of: flowercore --- 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 flowercore.io/github-repo: FlowerCore.Common spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-puppet-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.Puppet spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-signage-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.Signage spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-dms-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.DMS spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-telephony-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.Telephony spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-print-web-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.Print.Web spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-chat-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.Chat spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-mysql-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.MySQL spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: github-runner-kiosk-linux-nuget-cache namespace: github-runner labels: app.kubernetes.io/component: cache app.kubernetes.io/part-of: flowercore flowercore.io/github-repo: FlowerCore.Kiosk.Linux spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi volumeMode: Filesystem --- 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/github-repo: FlowerCore.Common spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: github-runner 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/github-repo: FlowerCore.Common spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always env: - name: REPO_URL value: "https://github.com/astoltz/FlowerCore.Common" - name: RUNNER_NAME_PREFIX value: "rke2-linux" - name: RUNNER_WORKDIR value: "/tmp/runner/work" - name: EPHEMERAL value: "true" - name: LABELS value: "self-hosted,linux,fc-build-linux" - 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.Puppet spec: replicas: 1 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/github-repo: FlowerCore.Puppet spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-puppet-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.Signage spec: replicas: 1 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/github-repo: FlowerCore.Signage spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-signage-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.DMS spec: replicas: 1 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/github-repo: FlowerCore.DMS spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-dms-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.Telephony spec: replicas: 1 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/github-repo: FlowerCore.Telephony spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-telephony-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.Print.Web spec: replicas: 1 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/github-repo: FlowerCore.Print.Web spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-print-web-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.Chat spec: replicas: 1 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/github-repo: FlowerCore.Chat spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-chat-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.MySQL spec: replicas: 1 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/github-repo: FlowerCore.MySQL spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-mysql-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always --- 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/github-repo: FlowerCore.Kiosk.Linux spec: replicas: 1 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/github-repo: FlowerCore.Kiosk.Linux spec: serviceAccountName: github-runner nodeSelector: kubernetes.io/hostname: rke2-server securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 containers: - name: runner image: myoung34/github-runner:latest imagePullPolicy: Always 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: 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: 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: nuget-cache persistentVolumeClaim: claimName: github-runner-kiosk-linux-nuget-cache - name: tmp emptyDir: {} restartPolicy: Always