2 Commits
Author SHA1 Message Date
rock 44d8e1e09d fix: always re-register runner to keep labels in sync with values.yaml
Init container skipped registration if .runner file existed on PVC.
Changing labels in values.yaml had no effect until PVC was manually
deleted — not GitOps-friendly.

Fix: rm -f .runner and re-register on every pod start.
2026-09-06 22:26:01 -07:00
rock 913cfc2f40 fix: add CoreDNS api.riotpiao.com rewrite + fix runner Alpine base image (#1)
1. Forgejo CI is broken across all repos

 Every workflow fails because runner labels point to a bare Alpine image with nothing in it.

 ┌────────────────────────────────────────┬──────────────────────────────────────┐
 │ Before                                 │ After                                │
 ├────────────────────────────────────────┼──────────────────────────────────────┤
 │ golang:docker://forgejo/runner:6       │ golang:docker://golang:1.26-bookworm │
 ├────────────────────────────────────────┼──────────────────────────────────────┤
 │ No Go, no Node.js, no apt-get, no root │ Go, git, apt-get, root               │
 └────────────────────────────────────────┴──────────────────────────────────────┘

 Plus the docker socket isn't shared between dind sidecar and runner, so even if docker CLI existed, it can't reach the daemon.

 ┌───────────────────────────────────────────┬─────────────────────────────────────────────────────────────┐
 │ Before                                    │ After                                                       │
 ├───────────────────────────────────────────┼─────────────────────────────────────────────────────────────┤
 │ dind creates socket in its own filesystem │ Shared /run emptyDir volume                                 │
 ├───────────────────────────────────────────┼─────────────────────────────────────────────────────────────┤
 │ Runner can't see it                       │ Both containers see /run/docker.sock                        │
 ├───────────────────────────────────────────┼─────────────────────────────────────────────────────────────┤
 │ No docker_host config                     │ docker_host: automount passes socket to workflow containers │

Co-authored-by: rock <[email protected]>
2026-09-07 05:19:39 +00:00
10 changed files with 24 additions and 115 deletions
-67
View File
@@ -1,67 +0,0 @@
name: Build and push runner images
on:
push:
paths:
- 'k8s/infra/forgejo-runner/Dockerfile.golang'
- 'k8s/infra/forgejo-runner/Dockerfile.rust'
- 'k8s/infra/forgejo-runner/Dockerfile.node'
branches:
- main
jobs:
build-runners:
runs-on: golang
env:
REGISTRY: forgejo.riotpiao.com
IMAGE_BASE: forgejo.riotpiao.com/rock
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get short SHA
id: sha
run: |
SHORT_SHA=$(git rev-parse --short HEAD)
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
- name: Registry login
run: |
echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" \
--username "${REGISTRY_USER}" --password-stdin
env:
REGISTRY_USER: ${{ secrets.FORGEJO_REGISTRY_USER }}
REGISTRY_TOKEN: ${{ secrets.FORGEJO_REGISTRY_TOKEN }}
- name: Build and push golang-runner
if: contains(github.event.head_commit.modified, 'Dockerfile.golang')
run: |
docker build -f k8s/infra/forgejo-runner/Dockerfile.golang \
-t "${IMAGE_BASE}/forgejo-runner-golang:${{ steps.sha.outputs.short_sha }}" \
-t "${IMAGE_BASE}/forgejo-runner-golang:latest" \
.
docker push "${IMAGE_BASE}/forgejo-runner-golang:${{ steps.sha.outputs.short_sha }}"
docker push "${IMAGE_BASE}/forgejo-runner-golang:latest"
echo "✓ Pushed golang-runner"
- name: Build and push rust-runner
if: contains(github.event.head_commit.modified, 'Dockerfile.rust')
run: |
docker build -f k8s/infra/forgejo-runner/Dockerfile.rust \
-t "${IMAGE_BASE}/forgejo-runner-rust:${{ steps.sha.outputs.short_sha }}" \
-t "${IMAGE_BASE}/forgejo-runner-rust:latest" \
.
docker push "${IMAGE_BASE}/forgejo-runner-rust:${{ steps.sha.outputs.short_sha }}"
docker push "${IMAGE_BASE}/forgejo-runner-rust:latest"
echo "✓ Pushed rust-runner"
- name: Build and push node-runner
if: contains(github.event.head_commit.modified, 'Dockerfile.node')
run: |
docker build -f k8s/infra/forgejo-runner/Dockerfile.node \
-t "${IMAGE_BASE}/forgejo-runner-node:${{ steps.sha.outputs.short_sha }}" \
-t "${IMAGE_BASE}/forgejo-runner-node:latest" \
.
docker push "${IMAGE_BASE}/forgejo-runner-node:${{ steps.sha.outputs.short_sha }}"
docker push "${IMAGE_BASE}/forgejo-runner-node:latest"
echo "✓ Pushed node-runner"
@@ -1,12 +0,0 @@
FROM code.forgejo.org/forgejo/runner:6
# Install Node.js + Docker client (needed for GitHub Actions + docker build)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
nodejs \
npm \
docker.io && \
rm -rf /var/lib/apt/lists/*
# Verify installations
RUN docker --version && node --version && git --version
-11
View File
@@ -1,11 +0,0 @@
FROM code.forgejo.org/forgejo/runner:6
# Install Docker client (forgejo/runner base doesn't include it)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
docker.io && \
rm -rf /var/lib/apt/lists/*
# Verify installations
RUN node --version && docker --version && git --version
# Trigger node-runner build with docker
-16
View File
@@ -1,16 +0,0 @@
FROM code.forgejo.org/forgejo/runner:6
# Install Node.js + Rust (needed for GitHub Actions checkout@v4, etc.)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
nodejs \
npm && \
rm -rf /var/lib/apt/lists/*
# Install Rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
# Verify installations
RUN docker --version && node --version && git --version && rustc --version
@@ -36,3 +36,4 @@ data:
valid_volumes: valid_volumes:
- /docker-certs/client - /docker-certs/client
network: host network: host
docker_host: automount
@@ -34,7 +34,11 @@ spec:
command: ["sh", "-c"] command: ["sh", "-c"]
args: args:
- | - |
test -f /data/.runner || forgejo-runner register --no-interactive \ # Always re-register to keep labels in sync with values.yaml.
# Without this, changing a runner label requires manually deleting
# the PVC or .runner file — not GitOps-friendly.
rm -f /data/.runner
forgejo-runner register --no-interactive \
--instance {{ .Values.runner.forgejoUrl }} \ --instance {{ .Values.runner.forgejoUrl }} \
--token $(RUNNER_TOKEN) \ --token $(RUNNER_TOKEN) \
--name {{ .Values.runner.name }} \ --name {{ .Values.runner.name }} \
@@ -70,6 +74,8 @@ spec:
mountPath: /data mountPath: /data
- name: docker-certs - name: docker-certs
mountPath: /docker-certs mountPath: /docker-certs
- name: docker-sock
mountPath: /run
- name: homelab-ca - name: homelab-ca
mountPath: /etc/ssl/certs/homelab-ca.pem mountPath: /etc/ssl/certs/homelab-ca.pem
subPath: ca.crt subPath: ca.crt
@@ -89,6 +95,8 @@ spec:
volumeMounts: volumeMounts:
- name: docker-certs - name: docker-certs
mountPath: /docker-certs mountPath: /docker-certs
- name: docker-sock
mountPath: /run
- name: dind-storage - name: dind-storage
mountPath: /var/lib/docker mountPath: /var/lib/docker
- name: homelab-ca - name: homelab-ca
@@ -113,6 +121,8 @@ spec:
claimName: {{ .Release.Name }}-dind claimName: {{ .Release.Name }}-dind
- name: docker-certs - name: docker-certs
emptyDir: {} # DinD regenerates mTLS certs on each start emptyDir: {} # DinD regenerates mTLS certs on each start
- name: docker-sock
emptyDir: {} # Shared docker socket between dind and runner
- name: homelab-ca - name: homelab-ca
# homelab-ca is a ConfigMap (public CA trust bundle), not a Secret. # homelab-ca is a ConfigMap (public CA trust bundle), not a Secret.
# The volumeMounts use subPath: ca.crt to project the single cert file. # The volumeMounts use subPath: ca.crt to project the single cert file.
+3 -4
View File
@@ -2,15 +2,14 @@
# runner instance. Only runner.name and runner.labels differ -- everything # runner instance. Only runner.name and runner.labels differ -- everything
# else (image, dind, persistence, tolerations, nodeSelector) is shared. # else (image, dind, persistence, tolerations, nodeSelector) is shared.
# #
# node:22-bookworm ships Node natively. Docker client installed via workflow step if needed. # Label image: node:22-bookworm — Debian, root, apt-get, Node.js, npm, git.
# (homelab has no CI; custom runner images built manually if desired) # Install docker in workflow steps as needed.
# Bootstrap with runner image (already has Node.js), CI builds custom
runner: runner:
image: image:
repository: code.forgejo.org/forgejo/runner repository: code.forgejo.org/forgejo/runner
tag: "6" tag: "6"
name: node-runner name: node-runner
labels: "node:docker://code.forgejo.org/forgejo/runner:6" labels: "node:docker://node:22-bookworm"
# GC CronJob renders only from the default (golang) values to avoid duplicates # GC CronJob renders only from the default (golang) values to avoid duplicates
gc: gc:
+3 -2
View File
@@ -2,13 +2,14 @@
# runner instance. Only runner.name and runner.labels differ -- everything # runner instance. Only runner.name and runner.labels differ -- everything
# else (image, dind, persistence, tolerations, nodeSelector) is shared. # else (image, dind, persistence, tolerations, nodeSelector) is shared.
# #
# Bootstrap with runner image, CI builds custom with Node.js+Rust # Label image: rust:1-bookworm — Debian, root, apt-get, Rust, cargo, git.
# Install Node.js/docker in workflow steps as needed.
runner: runner:
image: image:
repository: code.forgejo.org/forgejo/runner repository: code.forgejo.org/forgejo/runner
tag: "6" tag: "6"
name: rust-runner name: rust-runner
labels: "rust:docker://code.forgejo.org/forgejo/runner:6" labels: "rust:docker://rust:1-bookworm"
+5 -2
View File
@@ -1,9 +1,12 @@
runner: runner:
image: image:
repository: code.forgejo.org/forgejo/runner repository: code.forgejo.org/forgejo/runner
tag: "6" # Bootstrap with runner image, CI builds custom with Node.js tag: "6"
name: golang-runner name: golang-runner
labels: "golang:docker://code.forgejo.org/forgejo/runner:6" # Label image is what workflow steps run in (NOT the runner daemon image).
# golang:1.26-bookworm: Debian, root, apt-get, Go, git.
# Install Node.js/docker in workflow steps as needed.
labels: "golang:docker://golang:1.26-bookworm"
forgejoUrl: http://forgejo-gitea-http.cicd.svc.cluster.local:3000 forgejoUrl: http://forgejo-gitea-http.cicd.svc.cluster.local:3000
tokenSecret: runner-token tokenSecret: runner-token
resources: resources:
+1
View File
@@ -35,6 +35,7 @@
rewrite name longhorn.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local rewrite name longhorn.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
rewrite name paperless.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local rewrite name paperless.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
rewrite name img.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local rewrite name img.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
rewrite name api.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
rewrite name riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local rewrite name riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
kubernetes cluster.local in-addr.arpa ip6.arpa { kubernetes cluster.local in-addr.arpa ip6.arpa {