From bcdee225e507ab15f0a8fc3b6fd9e0141643014f Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sat, 24 Jan 2026 09:23:24 -0800 Subject: [PATCH] Replace k8s runner with ci-base image for local builds - Remove forgejo-runner k8s manifests and ArgoCD app (runner now on indri) - Remove build-runner workflow (no longer needed) - Add ci-base image with Ubuntu 22.04 + common CI tools - Add build-ci-base workflow to build the image - Update test workflow to check docker instead of buildah - Document bootstrap vs production mode for runner labels - Configure host.docker.internal:5050 for zot access from job containers Co-Authored-By: Claude Opus 4.5 --- .../{build-runner.yaml => build-ci-base.yaml} | 12 ++-- .forgejo/workflows/test.yaml | 17 +++-- .../roles/forgejo_runner/defaults/main.yml | 14 +++- argocd/apps/forgejo-runner.yaml | 23 ------- argocd/manifests/ci-base/Dockerfile | 58 ++++++++++++++++ argocd/manifests/forgejo-runner/Dockerfile | 67 ------------------- .../manifests/forgejo-runner/configmap.yaml | 13 ---- .../manifests/forgejo-runner/deployment.yaml | 63 ----------------- .../forgejo-runner/kustomization.yaml | 8 --- .../manifests/forgejo-runner/namespace.yaml | 4 -- .../forgejo-runner/secret-token.yaml.tpl | 10 --- .../forgejo-runner/serviceaccount.yaml | 5 -- 12 files changed, 85 insertions(+), 209 deletions(-) rename .forgejo/workflows/{build-runner.yaml => build-ci-base.yaml} (73%) delete mode 100644 argocd/apps/forgejo-runner.yaml create mode 100644 argocd/manifests/ci-base/Dockerfile delete mode 100644 argocd/manifests/forgejo-runner/Dockerfile delete mode 100644 argocd/manifests/forgejo-runner/configmap.yaml delete mode 100644 argocd/manifests/forgejo-runner/deployment.yaml delete mode 100644 argocd/manifests/forgejo-runner/kustomization.yaml delete mode 100644 argocd/manifests/forgejo-runner/namespace.yaml delete mode 100644 argocd/manifests/forgejo-runner/secret-token.yaml.tpl delete mode 100644 argocd/manifests/forgejo-runner/serviceaccount.yaml diff --git a/.forgejo/workflows/build-runner.yaml b/.forgejo/workflows/build-ci-base.yaml similarity index 73% rename from .forgejo/workflows/build-runner.yaml rename to .forgejo/workflows/build-ci-base.yaml index 44be98f..7a0d5f8 100644 --- a/.forgejo/workflows/build-runner.yaml +++ b/.forgejo/workflows/build-ci-base.yaml @@ -1,9 +1,9 @@ -name: Build forgejo-runner +name: Build CI base image on: push: tags: - - 'runner-v*' + - 'ci-base-v*' workflow_dispatch: inputs: version: @@ -23,8 +23,8 @@ jobs: if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then VERSION="${{ github.event.inputs.version }}" else - # Extract version from tag: runner-v1.0.0 -> v1.0.0 - VERSION="${GITHUB_REF_NAME#runner-}" + # Extract version from tag: ci-base-v1.0.0 -> v1.0.0 + VERSION="${GITHUB_REF_NAME#ci-base-}" fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "Building version: $VERSION" @@ -32,6 +32,6 @@ jobs: - name: Build and push uses: ./.forgejo/actions/build-push-image with: - context: argocd/manifests/forgejo-runner - image_name: blumeops/forgejo-runner + context: argocd/manifests/ci-base + image_name: blumeops/ci-base version: ${{ steps.version.outputs.version }} diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml index 1db41ee..b293ab7 100644 --- a/.forgejo/workflows/test.yaml +++ b/.forgejo/workflows/test.yaml @@ -16,23 +16,22 @@ jobs: - name: Verify tools run: | echo "=== Node.js ===" - node --version - npm --version + node --version || echo "Node.js not available" + npm --version || echo "npm not available" echo "" echo "=== Git ===" git --version echo "" echo "=== Build tools ===" - make --version 2>&1 | head -1 || true - gcc --version 2>&1 | head -1 || true + make --version 2>&1 | head -1 || echo "make not available" + gcc --version 2>&1 | head -1 || echo "gcc not available" echo "" - echo "=== Container tools (Buildah) ===" - buildah --version - podman --version + echo "=== Container tools (Docker) ===" + docker --version || echo "Docker CLI not available" echo "" echo "=== Other tools ===" - curl --version 2>&1 | head -1 || true - jq --version + curl --version 2>&1 | head -1 || echo "curl not available" + jq --version || echo "jq not available" - name: Show repo info run: | diff --git a/ansible/roles/forgejo_runner/defaults/main.yml b/ansible/roles/forgejo_runner/defaults/main.yml index c5dc8e6..e677240 100644 --- a/ansible/roles/forgejo_runner/defaults/main.yml +++ b/ansible/roles/forgejo_runner/defaults/main.yml @@ -8,7 +8,19 @@ forgejo_runner_log_dir: /Users/erichblume/Library/Logs # Runner registration forgejo_runner_instance_url: "http://localhost:3001" forgejo_runner_name: "indri-docker-runner" -forgejo_runner_labels: "docker-builder:docker,ubuntu-latest:docker,ubuntu-22.04:docker" +# Labels format: label:docker://image +# +# Bootstrap mode (use upstream images to build our own): +# docker-builder:docker://docker:27-cli +# ubuntu-latest:docker://catthehacker/ubuntu:act-22.04 +# +# Production mode (use our own images from zot via host.docker.internal): +# docker-builder:docker://host.docker.internal:5050/blumeops/ci-base:latest +# ubuntu-latest:docker://host.docker.internal:5050/blumeops/ci-base:latest +# +# Note: Docker daemon.json must include host.docker.internal:5050 in insecure-registries +# Currently using bootstrap mode until ci-base is built +forgejo_runner_labels: "docker-builder:docker://docker:27-cli,ubuntu-latest:docker://catthehacker/ubuntu:act-22.04,ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04" # Runner config forgejo_runner_capacity: 2 diff --git a/argocd/apps/forgejo-runner.yaml b/argocd/apps/forgejo-runner.yaml deleted file mode 100644 index a584d33..0000000 --- a/argocd/apps/forgejo-runner.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# Forgejo Actions Runner -# Runs in k8s, polls Forgejo for workflow jobs -# -# Before syncing, create the runner token secret: -# kubectl create namespace forgejo-runner -# op inject -i argocd/manifests/forgejo-runner/secret-token.yaml.tpl | kubectl apply -f - -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: forgejo-runner - namespace: argocd -spec: - project: default - source: - repoURL: ssh://forgejo@indri.tail8d86e.ts.net:2200/eblume/blumeops.git - targetRevision: main - path: argocd/manifests/forgejo-runner - destination: - server: https://kubernetes.default.svc - namespace: forgejo-runner - syncPolicy: - syncOptions: - - CreateNamespace=true diff --git a/argocd/manifests/ci-base/Dockerfile b/argocd/manifests/ci-base/Dockerfile new file mode 100644 index 0000000..974ceb2 --- /dev/null +++ b/argocd/manifests/ci-base/Dockerfile @@ -0,0 +1,58 @@ +# CI base image for Forgejo Actions +# Used by forgejo-runner for ubuntu-latest and ubuntu-22.04 labels +FROM ubuntu:22.04 + +# Prevent interactive prompts during package installation +ENV DEBIAN_FRONTEND=noninteractive + +# Install common CI tools +RUN apt-get update && apt-get install -y --no-install-recommends \ + # Essential tools + ca-certificates \ + curl \ + wget \ + git \ + jq \ + unzip \ + zip \ + # Build tools + build-essential \ + make \ + # Python + python3 \ + python3-pip \ + python3-venv \ + # Node.js (via nodesource for LTS) + && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y nodejs \ + # Docker CLI (not the daemon - we mount the socket) + && install -m 0755 -d /etc/apt/keyrings \ + && curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc \ + && chmod a+r /etc/apt/keyrings/docker.asc \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list \ + && apt-get update \ + && apt-get install -y docker-ce-cli \ + # Clean up + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Create a non-root user for running jobs +RUN useradd -m -s /bin/bash runner \ + && mkdir -p /home/runner/work \ + && chown -R runner:runner /home/runner + +# Set working directory +WORKDIR /home/runner/work + +# Default to runner user +USER runner + +# Verify installations +RUN echo "=== CI Base Image ===" \ + && git --version \ + && node --version \ + && npm --version \ + && python3 --version \ + && docker --version \ + && make --version | head -1 \ + && gcc --version | head -1 diff --git a/argocd/manifests/forgejo-runner/Dockerfile b/argocd/manifests/forgejo-runner/Dockerfile deleted file mode 100644 index 862f531..0000000 --- a/argocd/manifests/forgejo-runner/Dockerfile +++ /dev/null @@ -1,67 +0,0 @@ -# Build forgejo-runner from source -# Source: https://forge.tail8d86e.ts.net/eblume/forgejo-runner (mirror of code.forgejo.org/forgejo/runner) - -FROM golang:1.24-alpine AS builder - -ARG FORGEJO_RUNNER_VERSION=v3.5.1 - -RUN apk add --no-cache git make build-base - -WORKDIR /src -RUN git clone --depth 1 --branch ${FORGEJO_RUNNER_VERSION} \ - https://forge.tail8d86e.ts.net/eblume/forgejo-runner.git . - -RUN make clean && make build - -# Runtime image -FROM alpine:3.21 - -# Create runner user with proper passwd entry (required by buildah) -# Also configure subuid/subgid for rootless container builds -RUN addgroup -g 1000 runner && \ - adduser -D -u 1000 -G runner -h /data runner && \ - echo "runner:100000:65536" >> /etc/subuid && \ - echo "runner:100000:65536" >> /etc/subgid - -# Install runtime dependencies -RUN apk add --no-cache \ - # Required for actions/checkout and other Node-based actions - nodejs \ - npm \ - # Core tools - git \ - bash \ - curl \ - wget \ - jq \ - # Build essentials - make \ - gcc \ - g++ \ - musl-dev \ - # For container builds (daemonless, no Docker socket needed) - buildah \ - podman \ - fuse-overlayfs \ - ca-certificates - -# Copy runner binary from builder -COPY --from=builder /src/forgejo-runner /bin/forgejo-runner - -# Configure buildah for rootless operation -RUN mkdir -p /etc/containers && \ - printf '[storage]\ndriver = "overlay"\nrunroot = "/tmp/containers-run"\ngraphroot = "/tmp/containers-storage"\n[storage.options.overlay]\nmount_program = "/usr/bin/fuse-overlayfs"\n' \ - > /etc/containers/storage.conf - -# Configure registries (allow insecure for local registry) -RUN printf 'unqualified-search-registries = ["docker.io"]\n[[registry]]\nlocation = "registry.tail8d86e.ts.net"\ninsecure = true\n' \ - > /etc/containers/registries.conf - -# Verify tools are available -RUN node --version && npm --version && buildah --version && /bin/forgejo-runner --version - -ENV HOME=/data -WORKDIR /data -USER runner - -CMD ["/bin/forgejo-runner"] diff --git a/argocd/manifests/forgejo-runner/configmap.yaml b/argocd/manifests/forgejo-runner/configmap.yaml deleted file mode 100644 index 584efe0..0000000 --- a/argocd/manifests/forgejo-runner/configmap.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: forgejo-runner-config - namespace: forgejo-runner -data: - config.yaml: | - log: - level: info - runner: - file: /data/.runner - capacity: 1 - timeout: 3h diff --git a/argocd/manifests/forgejo-runner/deployment.yaml b/argocd/manifests/forgejo-runner/deployment.yaml deleted file mode 100644 index 79c70d3..0000000 --- a/argocd/manifests/forgejo-runner/deployment.yaml +++ /dev/null @@ -1,63 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: forgejo-runner - namespace: forgejo-runner -spec: - replicas: 1 - selector: - matchLabels: - app: forgejo-runner - template: - metadata: - labels: - app: forgejo-runner - spec: - serviceAccountName: forgejo-runner - containers: - - name: runner - image: registry.tail8d86e.ts.net/blumeops/forgejo-runner:v1.0.3 - env: - # Use internal k8s service via Tailscale operator egress - - name: FORGEJO_INSTANCE_URL - value: "http://forge.tailscale.svc.cluster.local:3001" - - name: RUNNER_NAME - value: "k8s-runner-1" - - name: RUNNER_TOKEN - valueFrom: - secretKeyRef: - name: forgejo-runner-token - key: token - command: - - /bin/sh - - -c - - | - # Register runner if not already registered - if [ ! -f /data/.runner ]; then - forgejo-runner register \ - --instance "$FORGEJO_INSTANCE_URL" \ - --token "$RUNNER_TOKEN" \ - --name "$RUNNER_NAME" \ - --labels "ubuntu-latest:host,ubuntu-22.04:host" \ - --no-interactive - fi - # Start the runner daemon with config - forgejo-runner daemon --config /config/config.yaml - volumeMounts: - - name: runner-data - mountPath: /data - - name: runner-config - mountPath: /config - resources: - requests: - memory: "256Mi" - cpu: "100m" - limits: - memory: "1Gi" - cpu: "1000m" - volumes: - - name: runner-data - emptyDir: {} - - name: runner-config - configMap: - name: forgejo-runner-config diff --git a/argocd/manifests/forgejo-runner/kustomization.yaml b/argocd/manifests/forgejo-runner/kustomization.yaml deleted file mode 100644 index 332c49c..0000000 --- a/argocd/manifests/forgejo-runner/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -namespace: forgejo-runner -resources: - - namespace.yaml - - serviceaccount.yaml - - configmap.yaml - - deployment.yaml diff --git a/argocd/manifests/forgejo-runner/namespace.yaml b/argocd/manifests/forgejo-runner/namespace.yaml deleted file mode 100644 index 19441b1..0000000 --- a/argocd/manifests/forgejo-runner/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: forgejo-runner diff --git a/argocd/manifests/forgejo-runner/secret-token.yaml.tpl b/argocd/manifests/forgejo-runner/secret-token.yaml.tpl deleted file mode 100644 index 427d8df..0000000 --- a/argocd/manifests/forgejo-runner/secret-token.yaml.tpl +++ /dev/null @@ -1,10 +0,0 @@ -# Template for op inject -# Usage: op inject -i secret-token.yaml.tpl | kubectl apply -f - -apiVersion: v1 -kind: Secret -metadata: - name: forgejo-runner-token - namespace: forgejo-runner -type: Opaque -stringData: - token: "op://blumeops/w3663ffnvkewbftncqxtcpeavy/runner_reg" diff --git a/argocd/manifests/forgejo-runner/serviceaccount.yaml b/argocd/manifests/forgejo-runner/serviceaccount.yaml deleted file mode 100644 index ef8cb25..0000000 --- a/argocd/manifests/forgejo-runner/serviceaccount.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: forgejo-runner - namespace: forgejo-runner