Migrate Forgejo runner to Kubernetes with DinD #60

Merged
eblume merged 15 commits from feature/containerized-runner into main 2026-01-25 19:56:17 -08:00
3 changed files with 124 additions and 0 deletions
Showing only changes of commit 008533491f - Show all commits

Add containerized forgejo-runner for Phase 1 ratcheting
Some checks failed
Build Container / build (push) Failing after 41s

Part of the runner ratcheting plan to migrate from host-mode to k8s runners.

- Debian-based image with forgejo-runner and Docker CLI
- Mounts Docker socket for container builds
- Auto-registers on first start
- Host networking for access to *.ops.eblu.me services

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erich Blume 2026-01-25 17:21:29 -08:00

View file

@ -0,0 +1,63 @@
# Forgejo Actions Runner - Containerized
#
# A containerized runner capable of building containers via Docker socket mount.
# Part of the runner ratcheting plan (Phase 1+).
#
# Build:
# docker build -t registry.ops.eblu.me/blumeops/forgejo-runner:v1.0.0 .
#
# Run (Phase 1 - Docker on indri):
# docker run -d \
# --name forgejo-runner \
# -v /var/run/docker.sock:/var/run/docker.sock \
# -e FORGEJO_URL=https://forge.ops.eblu.me \
# -e RUNNER_TOKEN=<token> \
# -e RUNNER_NAME=indri-docker-runner \
# registry.ops.eblu.me/blumeops/forgejo-runner:v1.0.0
#
# The runner registers itself on first start and persists state in /data.
FROM debian:bookworm-slim
# Forgejo runner version - check https://code.forgejo.org/forgejo/runner/releases
ARG RUNNER_VERSION=6.3.1
ARG TARGETARCH
# Install base dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
jq \
gnupg \
lsb-release \
&& rm -rf /var/lib/apt/lists/*
# Install Docker CLI (not daemon - we mount the socket)
RUN install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/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/debian $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends docker-ce-cli \
&& rm -rf /var/lib/apt/lists/*
# Install forgejo-runner
RUN ARCH=$(case "${TARGETARCH}" in "amd64") echo "amd64";; "arm64") echo "arm64";; *) echo "amd64";; esac) \
&& curl -fsSL "https://code.forgejo.org/forgejo/runner/releases/download/v${RUNNER_VERSION}/forgejo-runner-${RUNNER_VERSION}-linux-${ARCH}.xz" -o /tmp/runner.xz \
&& xz -d /tmp/runner.xz \
&& mv /tmp/runner /usr/local/bin/forgejo-runner \
&& chmod +x /usr/local/bin/forgejo-runner
# Create data directory for runner state
RUN mkdir -p /data
WORKDIR /data
# Copy entrypoint script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Copy runner config template
COPY config.yaml /etc/forgejo-runner/config.yaml
ENTRYPOINT ["/entrypoint.sh"]

View file

@ -0,0 +1,25 @@
# Forgejo Runner configuration
# See: https://forgejo.org/docs/latest/admin/actions/#configuration
log:
level: info
runner:
file: /data/.runner
capacity: 2
timeout: 3h
# Fetch task interval
fetch_timeout: 5s
fetch_interval: 2s
container:
# Use host network so containers can reach services on the host
# (e.g., registry.ops.eblu.me resolves to host's Tailscale IP)
network: host
# Don't use privileged mode by default
privileged: false
# Mount docker socket for container builds
options: -v /var/run/docker.sock:/var/run/docker.sock
# Valid volumes that can be mounted
valid_volumes:
- /var/run/docker.sock

View file

@ -0,0 +1,36 @@
#!/bin/bash
# Forgejo Runner entrypoint script
#
# Registers the runner on first start, then runs the daemon.
# State is persisted in /data so restarts don't re-register.
set -e
# Required environment variables
: "${FORGEJO_URL:?FORGEJO_URL is required (e.g., https://forge.ops.eblu.me)}"
: "${RUNNER_TOKEN:?RUNNER_TOKEN is required (from Forgejo admin > Actions > Runners)}"
# Optional environment variables with defaults
RUNNER_NAME="${RUNNER_NAME:-forgejo-runner}"
RUNNER_LABELS="${RUNNER_LABELS:-docker:docker://debian:bookworm-slim}"
# Registration file indicates runner is already registered
RUNNER_FILE="/data/.runner"
# Register if not already registered
if [ ! -f "$RUNNER_FILE" ]; then
echo "Registering runner '${RUNNER_NAME}' with ${FORGEJO_URL}..."
forgejo-runner register \
--instance "${FORGEJO_URL}" \
--token "${RUNNER_TOKEN}" \
--name "${RUNNER_NAME}" \
--labels "${RUNNER_LABELS}" \
--no-interactive
echo "Registration complete."
else
echo "Runner already registered, skipping registration."
fi
# Start the runner daemon
echo "Starting forgejo-runner daemon..."
exec forgejo-runner daemon --config /etc/forgejo-runner/config.yaml