From cfe5c0c0dd1078e770e6cdc84d3405cc18a9bf6a Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sat, 24 Jan 2026 13:23:39 -0800 Subject: [PATCH] Switch forgejo-runner to host execution mode Docker-based runner had networking issues reaching Forgejo from job containers. Host execution mode runs the runner daemon directly on indri, with jobs executing on the host. Actions that need Docker use host networking to access localhost:3001. - Runner binary compiled locally at ~/code/3rd/forgejo-runner - Labels use :host suffix instead of :docker://image - PATH set in launchd plist for mise-managed tools (node, etc.) - Container network set to "host" for actions needing Docker Co-Authored-By: Claude Opus 4.5 --- .../roles/forgejo_runner/defaults/main.yml | 41 +++++-------------- ansible/roles/forgejo_runner/tasks/main.yml | 25 +++-------- .../forgejo_runner/templates/config.yaml.j2 | 12 ++---- .../templates/forgejo-runner.plist.j2 | 34 ++++++--------- 4 files changed, 34 insertions(+), 78 deletions(-) diff --git a/ansible/roles/forgejo_runner/defaults/main.yml b/ansible/roles/forgejo_runner/defaults/main.yml index 6c87755..75cbd0c 100644 --- a/ansible/roles/forgejo_runner/defaults/main.yml +++ b/ansible/roles/forgejo_runner/defaults/main.yml @@ -1,42 +1,23 @@ --- -# Forgejo Runner - containerized daemon on tailnet-jobs network +# Forgejo Runner - host execution mode # -# The runner daemon runs in a Docker container with access to the tailnet -# via the tailscale-ci-gateway. This allows it to register with Forgejo -# using the Tailscale URL, so job containers can also reach Forgejo. +# The runner daemon runs directly on indri and executes jobs on the host. +# This avoids container networking complexity since it can reach Forgejo +# at localhost:3001 directly. +forgejo_runner_binary: /Users/erichblume/code/3rd/forgejo-runner/forgejo-runner forgejo_runner_data_dir: /Users/erichblume/.forgejo-runner forgejo_runner_config_dir: /Users/erichblume/.config/forgejo-runner forgejo_runner_log_dir: /Users/erichblume/Library/Logs -# Container settings -forgejo_runner_container_name: forgejo-runner -forgejo_runner_image: code.forgejo.org/forgejo/runner:6.2.1 -forgejo_runner_network: tailnet-jobs +# Runner registration - use localhost since we're running on indri +forgejo_runner_instance_url: "http://localhost:3001" +forgejo_runner_name: "indri-host-runner" -# Runner registration - use Tailscale URL since we're on tailnet-jobs network -forgejo_runner_instance_url: "https://forge.tail8d86e.ts.net" -forgejo_runner_name: "indri-docker-runner" - -# Labels format: label:docker://image -# -# Job containers also run on tailnet-jobs network and can reach: -# - forge.tail8d86e.ts.net for git clone -# - registry.tail8d86e.ts.net for container push/pull -# -# Bootstrap mode (use upstream images until we build ci-base): -# docker-builder:docker://docker:27-cli -# ubuntu-latest:docker://catthehacker/ubuntu:act-22.04 -# -# Production mode (use our own images from zot): -# docker-builder:docker://registry.tail8d86e.ts.net/blumeops/ci-base:latest -# ubuntu-latest:docker://registry.tail8d86e.ts.net/blumeops/ci-base:latest -# -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" +# Labels format for host execution: label:host +# Jobs run directly on the host, not in containers +forgejo_runner_labels: "ubuntu-latest:host,ubuntu-22.04:host" # Runner config forgejo_runner_capacity: 2 forgejo_runner_timeout: 3h - -# Docker container settings for jobs -forgejo_runner_privileged: true # Needed for container builds diff --git a/ansible/roles/forgejo_runner/tasks/main.yml b/ansible/roles/forgejo_runner/tasks/main.yml index 0cce725..0f28d88 100644 --- a/ansible/roles/forgejo_runner/tasks/main.yml +++ b/ansible/roles/forgejo_runner/tasks/main.yml @@ -1,12 +1,8 @@ --- -# Forgejo Runner - containerized daemon on tailnet-jobs network +# Forgejo Runner - host execution mode # -# The runner daemon runs in a Docker container with access to the tailnet -# via the tailscale-ci-gateway. Job containers also run on tailnet-jobs -# and can reach Forgejo via Tailscale. -# -# DEPENDENCIES: -# - tailscale_ci_gateway role must run first (creates tailnet-jobs network) +# The runner daemon runs directly on indri using a locally compiled binary. +# Jobs execute on the host, reaching Forgejo at localhost:3001. - name: Ensure forgejo-runner directories exist ansible.builtin.file: @@ -24,30 +20,21 @@ mode: '0644' notify: Restart forgejo-runner -- name: Pull forgejo-runner image - ansible.builtin.command: - cmd: docker pull {{ forgejo_runner_image }} - register: forgejo_runner_pull - changed_when: "'Downloaded newer image' in forgejo_runner_pull.stdout or 'Pull complete' in forgejo_runner_pull.stdout" - - name: Check if runner is registered ansible.builtin.stat: path: "{{ forgejo_runner_data_dir }}/.runner" register: forgejo_runner_registered -- name: Register runner with Forgejo (via tailnet) +- name: Register runner with Forgejo ansible.builtin.command: cmd: > - docker run --rm - --network=container:tailscale-ci-gateway - -v {{ forgejo_runner_data_dir }}:/data - {{ forgejo_runner_image }} - forgejo-runner register + {{ forgejo_runner_binary }} register --instance "{{ forgejo_runner_instance_url }}" --token "{{ forgejo_runner_token }}" --name "{{ forgejo_runner_name }}" --labels "{{ forgejo_runner_labels }}" --no-interactive + chdir: "{{ forgejo_runner_data_dir }}" when: not forgejo_runner_registered.stat.exists changed_when: true diff --git a/ansible/roles/forgejo_runner/templates/config.yaml.j2 b/ansible/roles/forgejo_runner/templates/config.yaml.j2 index 397fbbd..07bdb8d 100644 --- a/ansible/roles/forgejo_runner/templates/config.yaml.j2 +++ b/ansible/roles/forgejo_runner/templates/config.yaml.j2 @@ -3,15 +3,11 @@ log: level: info runner: - # Path inside the container (data dir mounted at /data) - file: /data/.runner + file: {{ forgejo_runner_data_dir }}/.runner capacity: {{ forgejo_runner_capacity }} timeout: {{ forgejo_runner_timeout }} +# Even in host execution mode, some actions run in containers. +# Use host networking so containers can access localhost services. container: - # Use tailnet-jobs network so job containers can reach Forgejo via Tailscale gateway - network: "{{ forgejo_runner_network }}" - privileged: {{ forgejo_runner_privileged | lower }} - # Mount Docker socket so jobs can build containers - valid_volumes: - - /var/run/docker.sock + network: "host" diff --git a/ansible/roles/forgejo_runner/templates/forgejo-runner.plist.j2 b/ansible/roles/forgejo_runner/templates/forgejo-runner.plist.j2 index e0d07a6..e04fa0d 100644 --- a/ansible/roles/forgejo_runner/templates/forgejo-runner.plist.j2 +++ b/ansible/roles/forgejo_runner/templates/forgejo-runner.plist.j2 @@ -7,28 +7,20 @@ mcquack.forgejo-runner ProgramArguments - /bin/bash - -c - /dev/null || true -/usr/local/bin/docker rm {{ forgejo_runner_container_name }} 2>/dev/null || true - -# Run the forgejo-runner daemon in a container -# - Uses gateway's network namespace for tailnet access (to poll Forgejo) -# - Mounts docker socket to spawn job containers -# - Mounts config and data directories -exec /usr/local/bin/docker run --rm \ - --name {{ forgejo_runner_container_name }} \ - --network=container:tailscale-ci-gateway \ - --user root \ - -v {{ ansible_env.HOME }}/.docker/run/docker.sock:/var/run/docker.sock \ - -v {{ forgejo_runner_config_dir }}/config.yaml:/config.yaml:ro \ - -v {{ forgejo_runner_data_dir }}:/data \ - {{ forgejo_runner_image }} \ - forgejo-runner daemon --config /config.yaml -]]> + {{ forgejo_runner_binary }} + daemon + --config + {{ forgejo_runner_config_dir }}/config.yaml + WorkingDirectory + {{ forgejo_runner_data_dir }} + EnvironmentVariables + + PATH + /Users/erichblume/.local/share/mise/shims:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + HOME + /Users/erichblume + RunAtLoad KeepAlive