agent and source files
This commit is contained in:
@@ -0,0 +1,421 @@
|
||||
<div align="center">
|
||||
|
||||
# custom-gitea-runner
|
||||
|
||||
A versioned, Docker-first, self-owned Gitea Actions runner platform for Unraid and Linux hosts.
|
||||
|
||||
[Overview](#overview) • [Goals](#goals) • [Architecture](#architecture) • [Repository-layout](#repository-layout) • [Quick-start](#quick-start) • [Environment](#environment) • [Roadmap](#roadmap) • [Operations](#operations)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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`](./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.
|
||||
Reference in New Issue
Block a user