200 lines
7.6 KiB
Markdown
200 lines
7.6 KiB
Markdown
# Gitea Act Runner
|
|
|
|
## Overview
|
|
|
|
Gitea Actions is Gitea's built-in CI/CD system, compatible with GitHub Actions workflows. The **Act Runner** is the agent that executes these workflows. It picks up jobs from a Gitea instance, spins up Docker containers for each workflow step, runs the commands, and reports results back.
|
|
|
|
The name "act" comes from [nektos/act](https://github.com/nektos/act), an open-source tool originally built to run GitHub Actions locally. Gitea forked and adapted it into their runner, so `act_runner` is a lineage artifact — the binary keeps the upstream name, but everything else in our infrastructure uses `gitea-runner`.
|
|
|
|
### How it works
|
|
|
|
1. The runner daemon polls the Gitea instance for queued workflow jobs
|
|
2. When a job is picked up, the runner pulls the Docker image specified by the workflow label (e.g., `ubuntu-24.04` maps to `docker.gitea.com/runner-images:ubuntu-24.04`)
|
|
3. Each workflow step executes inside an ephemeral container
|
|
4. Logs and status are streamed back to Gitea in real time
|
|
5. The container is destroyed after the job completes
|
|
|
|
### Architecture in Ouranos
|
|
|
|
```
|
|
Gitea (Rosalind) Act Runner (Puck)
|
|
┌──────────────┐ poll/report ┌──────────────────┐
|
|
│ gitea.ouranos │◄──────────────────│ act_runner daemon │
|
|
│ .helu.ca │ │ (gitea-runner) │
|
|
└──────────────┘ └────────┬─────────┘
|
|
│ spawns
|
|
┌────────▼─────────┐
|
|
│ Docker containers │
|
|
│ (workflow steps) │
|
|
└──────────────────┘
|
|
```
|
|
|
|
### Naming conventions
|
|
|
|
The **binary** is `act_runner` — that's the upstream package name and renaming it would break updates. Everything else uses `gitea-runner`:
|
|
|
|
| Component | Name |
|
|
|-----------|------|
|
|
| Binary | `/usr/local/bin/act_runner` (upstream, don't rename) |
|
|
| Service account | `gitea-runner` |
|
|
| Home directory | `/srv/gitea-runner/` |
|
|
| Config file | `/srv/gitea-runner/config.yaml` |
|
|
| Registration state | `/srv/gitea-runner/.runner` (created by registration) |
|
|
| Systemd service | `gitea-runner.service` |
|
|
| Runner name | `puck-runner` (shown in Gitea UI) |
|
|
|
|
---
|
|
|
|
## Ansible Deployment
|
|
|
|
The runner is deployed via the `gitea_runner` Ansible service to **Puck** (application runtime host with Docker already available).
|
|
|
|
### Prerequisites
|
|
|
|
- Docker must be installed on the target host (`docker` in services list)
|
|
- Gitea must be running and accessible at `https://gitea.ouranos.helu.ca`
|
|
|
|
### Deploy
|
|
|
|
```bash
|
|
# Deploy to all hosts with gitea_runner in their services list
|
|
ansible-playbook gitea_runner/deploy.yml
|
|
|
|
# Dry run (skip registration prompt)
|
|
ansible-playbook gitea_runner/deploy.yml --check
|
|
|
|
# Limit to a specific host
|
|
ansible-playbook gitea_runner/deploy.yml --limit puck.incus
|
|
|
|
# Non-interactive mode (for CI/CD)
|
|
ansible-playbook gitea_runner/deploy.yml -e registration_token=YOUR_TOKEN
|
|
```
|
|
|
|
The playbook is also included in the full-stack deployment via `site.yml`, running after the Gitea playbook.
|
|
|
|
**Registration Prompt**: On first deployment, the playbook will pause and prompt for a registration token. Get the token from `https://gitea.ouranos.helu.ca/-/admin/runners` before running the playbook.
|
|
|
|
### What the playbook does
|
|
|
|
1. Filters hosts — only runs on hosts with `gitea_runner` in their `services` list
|
|
2. Creates `gitea-runner` system group and user (added to `docker` group)
|
|
3. Downloads `act_runner` binary from Gitea releases (version pinned as `act_runner_version` in `group_vars/all/vars.yml`)
|
|
4. Skips download if the installed version already matches (idempotent)
|
|
5. Copies the managed `config.yaml` from the Ansible controller (edit `ansible/gitea_runner/config.yaml` to change runner settings)
|
|
6. Templates `gitea-runner.service` systemd unit
|
|
7. **Registers the runner** — prompts for registration token on first deployment
|
|
8. Enables and starts the service
|
|
|
|
### Systemd unit
|
|
|
|
```ini
|
|
# /etc/systemd/system/gitea-runner.service
|
|
[Unit]
|
|
Description=Gitea Runner
|
|
After=network.target docker.service
|
|
Requires=docker.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=gitea-runner
|
|
Group=gitea-runner
|
|
WorkingDirectory=/srv/gitea-runner
|
|
ExecStart=/usr/local/bin/act_runner daemon --config /srv/gitea-runner/config.yaml
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
Environment=HOME=/srv/gitea-runner
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
### Registration Flow
|
|
|
|
On first deployment, the playbook will automatically prompt for a registration token:
|
|
|
|
```
|
|
TASK [Prompt for registration token]
|
|
|
|
Gitea runner registration required.
|
|
Get token from: https://gitea.ouranos.helu.ca/-/admin/runners
|
|
|
|
Enter registration token:
|
|
[Enter token here]
|
|
```
|
|
|
|
**Steps**:
|
|
1. Before running the playbook, obtain a registration token:
|
|
- Navigate to `https://gitea.ouranos.helu.ca/-/admin/runners`
|
|
- Click "Create new Runner"
|
|
- Copy the displayed token
|
|
2. Run the deployment playbook
|
|
3. Paste the token when prompted
|
|
|
|
The registration is **idempotent** — if the runner is already registered (`.runner` file exists), the prompt is skipped.
|
|
|
|
**Non-interactive mode**: Pass the token as an extra variable:
|
|
```bash
|
|
ansible-playbook gitea_runner/deploy.yml -e registration_token=YOUR_TOKEN
|
|
```
|
|
|
|
**Manual registration** (if needed): The traditional method still works if you prefer manual control. Labels are picked up from `config.yaml` at daemon start, so `--labels` is not needed at registration:
|
|
```bash
|
|
ssh puck.incus
|
|
sudo -iu gitea-runner
|
|
act_runner register \
|
|
--instance https://gitea.ouranos.helu.ca \
|
|
--token <token> \
|
|
--name puck-runner \
|
|
--no-interactive
|
|
```
|
|
|
|
### Verify
|
|
|
|
```bash
|
|
# Check service status
|
|
sudo systemctl status gitea-runner
|
|
|
|
# Check runner version
|
|
act_runner --version
|
|
|
|
# View runner logs
|
|
sudo journalctl -u gitea-runner -f
|
|
```
|
|
|
|
`puck-runner` should show as **online** at `https://gitea.ouranos.helu.ca/-/admin/runners`.
|
|
|
|
### Runner labels
|
|
|
|
Labels map workflow `runs-on` values to Docker images. They are configured in `ansible/gitea_runner/config.yaml` under `runner.labels`:
|
|
|
|
| Label | Docker Image | Use case |
|
|
|-------|-------------|----------|
|
|
| `ubuntu-latest` | `docker.gitea.com/runner-images:ubuntu-latest` | General CI (Gitea official image) |
|
|
| `ubuntu-24.04` | `docker.gitea.com/runner-images:ubuntu-24.04` | Ubuntu 24.04 builds |
|
|
| `ubuntu-22.04` | `docker.gitea.com/runner-images:ubuntu-22.04` | Ubuntu 22.04 builds |
|
|
| `ubuntu-20.04` | `docker.gitea.com/runner-images:ubuntu-20.04` | Ubuntu 20.04 builds |
|
|
| `node-24` | `node:24-bookworm` | Node.js CI |
|
|
|
|
To add or change labels, edit `ansible/gitea_runner/config.yaml` and re-run the playbook.
|
|
|
|
### Configuration reference
|
|
|
|
| Variable | Location | Value |
|
|
|----------|----------|-------|
|
|
| `act_runner_version` | `group_vars/all/vars.yml` | `0.2.13` |
|
|
| `gitea_runner_instance_url` | `group_vars/all/vars.yml` | `https://gitea.ouranos.helu.ca` |
|
|
| `gitea_runner_name` | `host_vars/puck.incus.yml` | `puck-runner` |
|
|
| Runner labels | `ansible/gitea_runner/config.yaml` | See `runner.labels` section |
|
|
|
|
### Upgrading
|
|
|
|
To upgrade the runner binary, update `act_runner_version` in `group_vars/all/vars.yml` and re-run the playbook:
|
|
|
|
```bash
|
|
# Edit the version
|
|
vim inventory/group_vars/all/vars.yml
|
|
# act_runner_version: "0.2.14"
|
|
|
|
# Re-deploy — only the binary download and service restart will trigger
|
|
ansible-playbook gitea_runner/deploy.yml
|
|
``` |