diff --git a/container/README.md b/container/README.md index 1fd15f16..8937d7a9 100644 --- a/container/README.md +++ b/container/README.md @@ -54,25 +54,61 @@ The `reuse` job stays on the upstream `fsfe/reuse-action` (a Docker action the Docker executor launches as a sibling container) — nothing REUSE-related is baked into the SDK. -## CI runner (VM) +## CI runner (Alpine / OpenRC) -The runner runs in a small VM using the **Docker executor** (not the host -executor). This gives per-job container isolation and standard `ubuntu-latest` -semantics, and caps CI resources at the VM boundary. +The runner uses the **Docker executor** (not the host executor): per-job +container isolation and standard `ubuntu-latest` semantics. `act_runner` runs +as an OpenRC service. Files provided: -1. **Size the VM to your thread budget.** 2 vCPUs = a hard 2-thread ceiling. - Pin them to specific host threads so CI never touches the rest (libvirt/KVM): +| File | Purpose | +|------|---------| +| `act_runner.openrc` | OpenRC init script (`supervise-daemon`, depends on docker). | +| `act_runner.confd.example` | Per-instance `conf.d` settings for multi-runner hosts. | - ```xml - 2 - - - - - ``` +**Cap the thread budget.** In a VM, pin its vCPUs to specific host threads +(libvirt/KVM): -2. **Inside the VM:** install Docker (moby) and `act_runner`. -3. **Register one runner per project** (separate tokens from each repo's - *Settings → Actions → Runners*; scope keeps their jobs apart). -4. **Configure** with `runner-config.example.yaml` — `capacity: 1` and - `container.options: "--cpus=2"` keep usage inside the 2-thread budget. +```xml +2 + + + + +``` + +On bare metal, the `container.options: "--cpus=2"` and `capacity: 1` in +`runner-config.example.yaml` already bound each runner. + +**Set it up:** + +```bash +# 1. Docker + a dedicated user with socket access +apk add docker docker-cli +rc-update add docker default && rc-service docker start +adduser -S -D -H -h /var/lib/act_runner act +addgroup act docker + +# 2. act_runner binary (static Go build, works on musl) +curl -fsSL -o /usr/local/bin/act_runner \ + https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64 +chmod +x /usr/local/bin/act_runner + +# 3. Config + register one runner per project (scope keeps their jobs apart) +install -Dm644 container/runner-config.example.yaml /etc/act_runner/trx-rs.yaml +install -d -o act /var/lib/act_runner/trx-rs +su act -s /bin/sh -c 'cd /var/lib/act_runner/trx-rs && \ + act_runner register --no-interactive \ + --instance https://git.haxx.space --token \ + --name trx-rs-ci \ + --labels "ubuntu-latest:docker://catthehacker/ubuntu:act-latest"' + +# 4. OpenRC service (repeat the symlink+conf.d for the second project) +install -m755 container/act_runner.openrc /etc/init.d/act_runner +ln -s act_runner /etc/init.d/act_runner.trx-rs +install -m644 container/act_runner.confd.example /etc/conf.d/act_runner.trx-rs +rc-update add act_runner.trx-rs default +rc-service act_runner.trx-rs start +``` + +Check it with `rc-service act_runner.trx-rs status` and +`tail -f /var/log/act_runner.trx-rs.log`. diff --git a/container/act_runner.confd.example b/container/act_runner.confd.example new file mode 100644 index 00000000..b3ee409e --- /dev/null +++ b/container/act_runner.confd.example @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 Stan Grams +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Per-instance settings for an act_runner OpenRC service. +# Copy to /etc/conf.d/, e.g. /etc/conf.d/act_runner.trx-rs +# (the name must match the /etc/init.d/ symlink). + +# User that runs the daemon. Must be a member of the `docker` group. +runner_user="act" + +# Per-instance state dir (holds the .runner registration) and config file, +# so two runners on one host stay independent. +runner_dir="/var/lib/act_runner/trx-rs" +runner_config="/etc/act_runner/trx-rs.yaml" diff --git a/container/act_runner.openrc b/container/act_runner.openrc new file mode 100644 index 00000000..5c87aff3 --- /dev/null +++ b/container/act_runner.openrc @@ -0,0 +1,44 @@ +#!/sbin/openrc-run +# SPDX-FileCopyrightText: 2026 Stan Grams +# SPDX-License-Identifier: GPL-2.0-or-later +# +# OpenRC service for a Gitea act_runner (Docker executor) on Alpine. +# +# Install as /etc/init.d/act_runner (chmod +x). Single instance uses +# /etc/act_runner/config.yaml. For one runner per project, symlink this script +# and add a matching conf.d file: +# +# ln -s act_runner /etc/init.d/act_runner.trx-rs +# cp container/act_runner.confd.example /etc/conf.d/act_runner.trx-rs +# $EDITOR /etc/conf.d/act_runner.trx-rs # set runner_dir / runner_config +# rc-update add act_runner.trx-rs default +# rc-service act_runner.trx-rs start + +description="Gitea Actions runner" + +: "${runner_user:=act}" +: "${runner_dir:=/var/lib/act_runner}" +: "${runner_config:=/etc/act_runner/config.yaml}" + +command="/usr/local/bin/act_runner" +command_args="daemon --config ${runner_config}" +# No group given, so supplementary groups (incl. docker) are initialised. +command_user="${runner_user}" +directory="${runner_dir}" + +supervisor="supervise-daemon" +respawn_delay=5 +respawn_max=0 +pidfile="/run/${RC_SVCNAME}.pid" +output_log="/var/log/${RC_SVCNAME}.log" +error_log="/var/log/${RC_SVCNAME}.log" + +depend() { + need docker + use net dns +} + +start_pre() { + checkpath -d -m 0750 -o "${runner_user}" "${runner_dir}" + checkpath -f -m 0640 -o "${runner_user}" "${output_log}" +}