An auto-setting up forgejo runner supporting docker in docker
  • PowerShell 51.4%
  • Shell 29.5%
  • Ruby 19.1%
Find a file
Zach Handley 34e9aec81b
Some checks are pending
CI - ForgejoRunner / Test Chocolatey Package (push) Waiting to run
CI - ForgejoRunner / CI Summary (push) Blocked by required conditions
CI - ForgejoRunner / trigger-build (push) Blocked by required conditions
CI - ForgejoRunner / Lint Shell Scripts (push) Successful in 2s
Fixes for containers and stuff
2026-03-26 18:10:46 -07:00
.forgejo/workflows [release] Another fix 2026-03-15 20:05:59 -07:00
chocolatey Release v12.7.2.2 (upstream v12.7.2) 2026-03-16 03:07:10 +00:00
common/scripts Fix install.sh using latest 2026-03-26 16:32:13 -07:00
Formula Release v12.7.2.2 (upstream v12.7.2) 2026-03-16 03:07:10 +00:00
homebrew missed a thing 2026-03-13 10:35:13 -07:00
launchd Initial commit 2026-03-13 10:35:03 -07:00
patches Fixes for containers and stuff 2026-03-26 18:10:46 -07:00
scripts Fix install.sh using latest 2026-03-26 16:32:13 -07:00
systemd Initial commit 2026-03-13 10:35:03 -07:00
vendor Initial commit 2026-03-13 10:35:03 -07:00
.gitmodules Initial commit 2026-03-13 10:35:03 -07:00
LICENSE Initial commit 2025-11-30 00:51:03 +00:00
README.md [release] Fixes for build 2026-03-13 14:02:55 -07:00

Forgejo Runner

Patched Forgejo Actions runner for macOS, Linux, and Windows with automatic service installation, cache management, and system tool integration.

This is not the upstream Forgejo runner - it's a patched distribution that adds turnkey service management. The register command automatically installs and starts the system service, eliminating manual setup.

I separated this recently from ForgejoResources to create a ZArcRunner using ZLayer

Features

  • Automatic service installation - register creates and starts systemd/launchd/Windows service
  • Cache management - Built-in cache clean and scheduled cleanup
  • Install/Uninstall commands - Full lifecycle management
  • Environment regeneration - regen-env captures shell environment for tools
  • Cross-platform - Linux, macOS, Windows with native service integration
  • Register flags - --no-service, --user-service, --install-tools

Quick Install

Linux

curl -fsSL https://forge.blackleafdigital.com/Public/ForgejoRunner/raw/branch/main/scripts/install-linux.sh | bash

macOS

curl -fsSL https://forge.blackleafdigital.com/Public/ForgejoRunner/raw/branch/main/scripts/install-macos.sh | bash

Windows (PowerShell as Admin)

irm https://forge.blackleafdigital.com/Public/ForgejoRunner/raw/branch/main/scripts/install-windows.ps1 | iex

Homebrew (macOS)

brew tap blackleafdigital/forgejorunner https://forge.blackleafdigital.com/Public/ForgejoRunner.git
brew install forgejo-runner

Chocolatey (Windows)

choco install forgejo-runner

Registration

After installation, register with your Forgejo instance:

forgejo-runner register \
  --instance https://your-forgejo.com \
  --token YOUR_RUNNER_TOKEN

This automatically:

  1. Creates config directories
  2. Registers with Forgejo
  3. Installs the system service (systemd/launchd/Windows Service)
  4. Starts the runner

Skip Service Installation

If you want to manage the service yourself:

forgejo-runner register \
  --instance https://your-forgejo.com \
  --token YOUR_TOKEN \
  --no-service

Non-Interactive Mode

forgejo-runner register \
  --no-interactive \
  --instance https://your-forgejo.com \
  --token YOUR_TOKEN \
  --name "my-runner" \
  --labels "ubuntu-latest:host,docker:host"

All Register Flags

Flag Description
--no-service Skip automatic service installation
--user-service Install as user-level service (Linux only, uses ~/.config/systemd/user/)
--install Run system installation before registration
--install-tools <categories> Install tools during registration (e.g., docker,node,go)

User-Level vs System-Wide (Linux)

# System-wide (requires root, uses /etc/forgejo-runner/)
sudo forgejo-runner register --instance ... --token ...

# User-level (no root, uses ~/.config/forgejo-runner/)
forgejo-runner register --instance ... --token ... --user-service

Service Management

Linux (root install)

sudo systemctl status forgejo-runner
sudo systemctl restart forgejo-runner
sudo journalctl -u forgejo-runner -f

Linux (user install)

systemctl --user status forgejo-runner
systemctl --user restart forgejo-runner
journalctl --user -u forgejo-runner -f

# Keep service running after logout
sudo loginctl enable-linger $USER

macOS

launchctl list | grep forgejo
launchctl stop com.forgejo.runner
launchctl start com.forgejo.runner

Windows

Get-Service ForgejoRunner
Restart-Service ForgejoRunner
sc query ForgejoRunner

Cache Management

The runner includes built-in cache management to clean up old workflow cache entries.

Clean Cache Manually

# Preview what would be deleted (dry run)
forgejo-runner cache clean --dry-run --verbose

# Clean entries older than 7 days (default)
forgejo-runner cache clean

# Clean entries older than 3 days
forgejo-runner cache clean --age 3

Install Automatic Cleanup

Install a scheduled task to automatically clean the cache:

# Install daily cleanup (default)
forgejo-runner cache install

# Install with custom interval and age
forgejo-runner cache install --interval weekly --age 14

This creates:

  • Linux: systemd timer
  • macOS: launchd plist
  • Windows: scheduled task

Cache Lock Protection

The cache cleaner respects active tasks:

  • When a task starts, a lock file is created
  • Cache entries won't be deleted while tasks are running
  • Stale locks (>24h) are automatically cleaned up

Install Command

The install command downloads and runs platform-specific installation scripts:

# Install the runner (downloads binary, sets up paths)
forgejo-runner install

# Install with specific tool categories
forgejo-runner install --tools docker,node,go,rust

# User-level installation (Linux)
forgejo-runner install --user-service

Tool categories: docker, node, python, java, go, rust, php, ruby, dotnet

Uninstall Command

Cleanly remove the runner and optionally its data:

# Full uninstall (removes service, config, data)
forgejo-runner uninstall

# Keep configuration and data
forgejo-runner uninstall --keep-data

# Keep installed system tools
forgejo-runner uninstall --keep-tools

Regen-env Command

Regenerates the environment file by capturing the login shell environment:

forgejo-runner regen-env

This spawns a login shell (bash, zsh, etc.) and captures the resulting environment, including:

  • Homebrew/Linuxbrew shell environment
  • NVM, pyenv, rbenv, and other version managers
  • PATH and other variables from .bashrc, .zshrc, .zprofile, etc.

The environment is written to:

  • Linux (root): /etc/forgejo-runner/env
  • Linux (user): ~/.config/forgejo-runner/env
  • macOS: ~/.config/forgejo-runner/env

Use this after: Installing new tools via brew, nvm, or modifying shell configuration.

File Locations

Linux (root)

Type Path
Binary /usr/local/bin/forgejo-runner
Config /etc/forgejo-runner/config.yaml
Data /var/lib/forgejo-runner/
Logs /var/log/forgejo-runner/
Service /etc/systemd/system/forgejo-runner.service

Linux (user)

Type Path
Binary ~/.local/bin/forgejo-runner
Config ~/.config/forgejo-runner/config.yaml
Data ~/.local/share/forgejo-runner/
Service ~/.config/systemd/user/forgejo-runner.service

macOS

Type Path
Binary /usr/local/bin/forgejo-runner or ~/.local/bin/forgejo-runner
Config ~/.config/forgejo-runner/config.yaml
Data ~/Library/Application Support/ForgejoRunner/
Logs ~/Library/Application Support/ForgejoRunner/logs/
Service ~/Library/LaunchAgents/com.forgejo.runner.plist

Windows

Type Path
Binary C:\Program Files\ForgejoRunner\forgejo-runner.exe
Config C:\ProgramData\forgejorunner\config.yaml
Data C:\ProgramData\forgejorunner\
Logs C:\ProgramData\forgejorunner\logs\

Labels

Common labels to use during registration:

# Host-based execution
--labels "ubuntu-latest:host,linux:host,docker:host"

# Docker-based execution
--labels "ubuntu-latest:docker://node:20-bookworm"

Troubleshooting

Check if runner is registered

# Linux/macOS
cat /var/lib/forgejo-runner/.runner   # root
cat ~/.local/share/forgejo-runner/.runner  # user

# Windows
Get-Content C:\ProgramData\forgejorunner\.runner

View logs

# Linux
sudo journalctl -u forgejo-runner -f

# macOS
tail -f ~/Library/Application\ Support/ForgejoRunner/logs/stdout.log

# Windows
Get-Content C:\ProgramData\forgejorunner\logs\stdout.log -Tail 50 -Wait

Service won't start

  1. Check if .runner file exists (registration succeeded)
  2. Check if config.yaml exists and is valid
  3. Check logs for errors

Re-register

# Stop and remove existing service first
sudo systemctl stop forgejo-runner
sudo rm /etc/systemd/system/forgejo-runner.service

# Re-register
forgejo-runner register --instance ... --token ...

System Tools Installation

For host-based runners, install development tools using the built-in command:

# Install all tools (requires root)
sudo forgejo-runner install-system-tools

# Install specific categories
sudo forgejo-runner install-system-tools --tools docker,node,go,rust

Or use the script directly:

sudo curl -fsSL https://forge.blackleafdigital.com/Public/ForgejoRunner/raw/branch/main/scripts/install-system-tools.sh | bash

Available tool categories: core, docker, dev, cloud, k8s, db, testing, java, dotnet, flutter

This installs via Homebrew/Linuxbrew:

Category Tools
Core git, git-lfs, gh, jq, yq, curl, wget, make, cmake, gcc
Containers Docker, Podman, Buildah, Skopeo
Languages Node.js, Go, Rust, Python, PHP, Ruby, Java, .NET, Flutter
Cloud CLIs AWS CLI, Azure CLI, Google Cloud SDK, DigitalOcean, Fly.io
Kubernetes kubectl, Helm, kind, k9s
Databases MySQL, PostgreSQL, Redis, SQLite, MongoDB clients
Testing ShellCheck, Hadolint, Trivy, Cosign

Building from Source

The build workflow automatically applies our service installation patch to upstream Forgejo runner:

# Clone upstream
git clone --depth 1 --branch v12.1.0 https://code.forgejo.org/forgejo/runner.git
cd runner

# Apply our patch
git apply /path/to/ForgejoRunner/patches/forgejo-runner-service.patch

# Build
CGO_ENABLED=0 make build

Patch Contents

The patches/forgejo-runner-service.patch transforms upstream forgejo-runner into a turnkey solution:

New Commands

Command Description
cache clean Remove old cache entries (respects active task locks)
cache install Install scheduled cache cleanup (systemd timer/launchd/Windows task)
install Download and run platform-specific installation
uninstall Remove runner, service, and optionally data/tools
regen-env Regenerate environment file from login shell
install-system-tools Install dev tools via Homebrew (docker, node, go, etc.)

Register Enhancements

Flag Description
--no-service Skip automatic service installation
--user-service Install as user-level service (Linux)
--install Run installation before registration
--install-tools Install tools during registration

System-Wide Install (Linux root)

When registering as root, the patch automatically:

  1. Creates forgejo-runner system user
  2. Creates /etc/forgejo-runner/, /var/lib/forgejo-runner/, /var/cache/forgejo-runner/
  3. Copies .runner and generates config.yaml with system paths
  4. Generates /etc/forgejo-runner/env with shell environment
  5. Installs hardened systemd service (runs as forgejo-runner user)
  6. Starts the service

Files Added by Patch

  • service.go - Cross-platform service installation
  • cache.go - Cache management with lock protection
  • install.go - Install/uninstall commands
  • regen_env.go - Environment regeneration
  • install_system_tools.go - System tools installation command