Files
forgerunner/forgerunner.src/README.md
T
2026-06-29 17:33:15 -05:00

11 KiB

custom-gitea-runner

A versioned, Docker-first, self-owned Gitea Actions runner platform for Unraid and Linux hosts.

OverviewGoalsArchitectureRepository-layoutQuick-startEnvironmentRoadmapOperations


Overview

custom-gitea-runner is a controlled replacement for opaque runner setups that are difficult to debug, mutate at startup, or break unexpectedly when upstream images or runtime assumptions change.

The project packages a Gitea-compatible runner into a predictable Docker image with pinned dependencies, explicit startup logic, clean documentation, and testable operational workflows. The goal is to make the runner understandable, inspectable, and easy to version over time.

This repository is designed for self-hosted environments where the operator wants direct control over:

  • base image selection,
  • bundled tooling,
  • startup and registration flow,
  • Docker socket/build behavior,
  • release/version policy,
  • troubleshooting and rollback.

Why this exists

This project exists to eliminate common self-hosted runner pain points such as:

  • missing runtime dependencies like Node.js, Git, or Docker CLI,
  • fragile startup behavior that depends on mutable package installs,
  • difficult-to-diagnose nested container failures,
  • unclear registration/config persistence,
  • and weak operational visibility when jobs fail early.

Instead of treating the runner like a disposable black box, this repository treats it like an internal platform component.


Goals

Primary goals

  • Build a custom Docker image for a Gitea-compatible runner.
  • Bundle required CI dependencies at image build time.
  • Support checkout, Node-based actions, Docker login, Docker build, and Docker push workflows.
  • Provide deterministic bootstrap and registration behavior.
  • Provide clean deployment guidance for Unraid and standard Linux Docker hosts.
  • Keep all operational knowledge versioned in-repo.

Secondary goals

  • Support custom CA trust.
  • Support opinionated label templates.
  • Support smoke testing and regression fixtures.
  • Support future hardening tracks like rootless or DinD variants.

Non-goals

  • Replacing Gitea itself.
  • Building a full control plane or autoscaling runner manager in v1.
  • Solving every orchestration model on day one.

Architecture

Design principles

  • Deterministic image builds.
  • No hidden runtime package installs in normal operation.
  • Explicit entrypoint and healthcheck behavior.
  • Pinned versions where practical.
  • Clear separation of image build, registration, runtime config, and operations.
  • Logs that are useful during failure, not just success.

Planned v1 stack

  • Debian slim or Ubuntu slim base image.
  • Pinned act_runner binary or pinned upstream release artifact.
  • Bundled tooling:
    • bash
    • curl
    • git
    • jq
    • node
    • npm
    • docker
    • ca-certificates
    • tini
  • Entrypoint script for validation, registration, and daemon startup.
  • Healthcheck script for runtime verification.
  • Example config and compose files.

Runtime model

The runner container is intended to be long-lived and operator-managed.

Preferred v1 modes:

  1. Pre-generated config mounted into the container.
  2. Environment-driven one-time bootstrap registration when config is absent.

For Docker build/push workflows, v1 assumes a trusted host and supports a mounted Docker socket. Future variants can harden or isolate this behavior.


Repository layout

custom-gitea-runner/
├── AGENT.md
├── README.md
├── ROADMAP.md
├── CHANGELOG.md
├── LICENSE
├── .gitignore
├── .env.example
├── docker/
│   ├── runner/
│   │   ├── Dockerfile
│   │   ├── docker-entrypoint.sh
│   │   ├── healthcheck.sh
│   │   └── smoke-test.sh
│   └── compose/
│       ├── docker-compose.example.yml
│       └── unraid-template-notes.md
├── config/
│   ├── runner.example.yaml
│   ├── labels.example.env
│   └── trusted-ca/
├── scripts/
│   ├── register-runner.sh
│   ├── deregister-runner.sh
│   ├── verify-runtime.sh
│   ├── build-image.sh
│   ├── publish-image.sh
│   └── test-local-runner.sh
├── docs/
│   ├── architecture.md
│   ├── operations.md
│   ├── troubleshooting.md
│   ├── unraid.md
│   └── decisions/
│       └── 0001-base-image.md
├── test/
│   ├── fixtures/
│   ├── sample-workflows/
│   └── smoke/
└── src/
    └── optional/

Quick start

1. Create the repository

Create a new Gitea repository named custom-gitea-runner and commit the initial documentation set:

  • AGENT.md
  • README.md
  • ROADMAP.md
  • CHANGELOG.md
  • .gitignore
  • .env.example

2. Build the first image

Once the Dockerfile exists:

docker build -t custom-gitea-runner:v0.1.0 -f docker/runner/Dockerfile .

3. Provide runtime configuration

Create a .env file from .env.example and decide whether to:

  • mount a pre-generated runner config, or
  • let the container self-register on first boot.

4. Start the runner

Use Docker Compose or the equivalent Unraid template settings to start the container with:

  • persistent config mount,
  • persistent work directory,
  • Docker socket mount if build/push is required,
  • required env vars.

5. Run smoke workflows

Before production use, validate at minimum:

  • checkout-only workflow,
  • Node-based action workflow,
  • Docker login workflow,
  • Docker build/push workflow.

Environment

Planned environment variables for bootstrap mode:

Variable Required Purpose
GITEA_INSTANCE_URL Yes Base URL of the Gitea instance.
GITEA_RUNNER_TOKEN Yes Registration token for the runner.
GITEA_RUNNER_NAME Yes Human-readable runner name.
GITEA_RUNNER_LABELS No Comma-separated label list.
GITEA_RUNNER_WORKDIR No Working directory inside the container.
GITEA_RUNNER_CONFIG_PATH No Path to the runner config file.
TZ No Time zone for logs and runtime behavior.

Future environment variables may include:

  • custom CA paths,
  • logging mode,
  • healthcheck tuning,
  • Docker socket override,
  • feature flags for experimental runner behavior.

Example deployment model

Docker Compose direction

The project will include a compose example that follows this pattern:

  • pinned image tag,
  • mounted runner config,
  • mounted work directory,
  • mounted Docker socket,
  • explicit restart policy,
  • explicit environment variables.

Example shape:

services:
  gitea-runner:
    image: custom-gitea-runner:v0.1.0
    container_name: custom-gitea-runner
    restart: unless-stopped
    environment:
      GITEA_INSTANCE_URL: https://git.example.com
      GITEA_RUNNER_NAME: unraid-runner-01
      GITEA_RUNNER_TOKEN: ${GITEA_RUNNER_TOKEN}
      GITEA_RUNNER_LABELS: ubuntu-latest,docker
      TZ: America/Chicago
    volumes:
      - ./config:/config
      - ./work:/work
      - /var/run/docker.sock:/var/run/docker.sock

Unraid direction

The Unraid notes should document:

  • repository/image field,
  • appdata path recommendations,
  • variable definitions,
  • volume mounts,
  • Docker socket usage,
  • update workflow,
  • rollback workflow.

Operations

Expected startup behavior

At startup, the container should log:

  • image version,
  • embedded git revision if available,
  • act_runner version,
  • node version,
  • docker version,
  • config path,
  • work path,
  • registration mode,
  • target Gitea URL,
  • active labels.

Health behavior

The healthcheck should confirm:

  • runner process is alive,
  • config exists,
  • required tools exist,
  • Docker socket is available when configured.

Upgrade workflow

Recommended upgrade process:

  1. Pull or build a new pinned image tag.
  2. Review CHANGELOG.md.
  3. Stop the existing container.
  4. Update image tag in compose or Unraid template.
  5. Start the container.
  6. Verify logs and healthcheck.
  7. Run smoke workflow.

Rollback workflow

  1. Stop the container.
  2. Revert to prior known-good image tag.
  3. Start the container.
  4. Verify registration/config still valid.
  5. Confirm smoke workflow success.

Documentation set

This repository should maintain the following docs as first-class assets:

  • AGENT.md — build rules, architecture constraints, agent instructions.
  • README.md — project overview, install/use guidance, operational entry point.
  • ROADMAP.md — phased plan with active status tracking.
  • CHANGELOG.md — release history.
  • docs/architecture.md — deeper design details.
  • docs/operations.md — runtime/admin guidance.
  • docs/troubleshooting.md — symptom-driven fixes.
  • docs/unraid.md — Unraid-specific deployment instructions.
  • docs/decisions/*.md — ADR-style architecture decisions.

Testing strategy

Required validation layers:

  • image build verification,
  • runtime tool verification,
  • registration smoke tests,
  • workflow smoke tests,
  • regression tests for previously encountered failure classes.

The first workflows to validate should be:

  1. actions/checkout
  2. Node-based action execution
  3. docker/login-action
  4. docker build
  5. docker push

Roadmap

Project planning lives in ROADMAP.md.

High-level phases:

  • Phase 0: Research and design
  • Phase 1: Base image and bootstrap
  • Phase 2: Registration/config flows
  • Phase 3: Docker workflow support
  • Phase 4: Test harness and smoke validation
  • Phase 5: Unraid packaging and docs
  • Phase 6: Hardening and enhancements

Release model

Recommended versioning:

  • v0.1.0
  • v0.1.1
  • v0.2.0

latest may exist as a convenience tag, but documentation should always recommend pinned versions for real deployments.

Every release should map to:

  • a Git tag,
  • a CHANGELOG entry,
  • image metadata labels,
  • and documented upgrade notes where relevant.

Contributing workflow

Recommended development loop:

  1. Update docs first when requirements or behavior change.
  2. Make small, reviewable changes.
  3. Keep scripts simple and auditable.
  4. Add regression coverage for painful bugs.
  5. Prefer explicit configuration over implicit behavior.

Current status

This repository is in planning/bootstrap stage.

The immediate next steps are:

  • finalize the architecture direction,
  • scaffold the repository,
  • build the first pinned image,
  • implement registration/bootstrap scripts,
  • validate smoke workflows,
  • document Unraid deployment.