[chore](trx-rs): add OpenRC service for act_runner on Alpine
The runner host is Alpine (OpenRC, no systemd). Add an OpenRC init script for act_runner (supervise-daemon, depends on docker) plus a conf.d example for running one instance per project, and rewrite the runner section of the README with Alpine setup steps (apk docker, dedicated user in the docker group, register, service install). Assisted-By: Claude Code (claude-opus-4) Claude-Session: https://claude.ai/code/session_01NFpGtGTWUEYXLwZeZs2RAV Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
+47
-11
@@ -54,14 +54,19 @@ 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
|
Docker executor launches as a sibling container) — nothing REUSE-related is
|
||||||
baked into the SDK.
|
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
|
The runner uses the **Docker executor** (not the host executor): per-job
|
||||||
executor). This gives per-job container isolation and standard `ubuntu-latest`
|
container isolation and standard `ubuntu-latest` semantics. `act_runner` runs
|
||||||
semantics, and caps CI resources at the VM boundary.
|
as an OpenRC service. Files provided:
|
||||||
|
|
||||||
1. **Size the VM to your thread budget.** 2 vCPUs = a hard 2-thread ceiling.
|
| File | Purpose |
|
||||||
Pin them to specific host threads so CI never touches the rest (libvirt/KVM):
|
|------|---------|
|
||||||
|
| `act_runner.openrc` | OpenRC init script (`supervise-daemon`, depends on docker). |
|
||||||
|
| `act_runner.confd.example` | Per-instance `conf.d` settings for multi-runner hosts. |
|
||||||
|
|
||||||
|
**Cap the thread budget.** In a VM, pin its vCPUs to specific host threads
|
||||||
|
(libvirt/KVM):
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<vcpu placement='static'>2</vcpu>
|
<vcpu placement='static'>2</vcpu>
|
||||||
@@ -71,8 +76,39 @@ semantics, and caps CI resources at the VM boundary.
|
|||||||
</cputune>
|
</cputune>
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Inside the VM:** install Docker (moby) and `act_runner`.
|
On bare metal, the `container.options: "--cpus=2"` and `capacity: 1` in
|
||||||
3. **Register one runner per project** (separate tokens from each repo's
|
`runner-config.example.yaml` already bound each runner.
|
||||||
*Settings → Actions → Runners*; scope keeps their jobs apart).
|
|
||||||
4. **Configure** with `runner-config.example.yaml` — `capacity: 1` and
|
**Set it up:**
|
||||||
`container.options: "--cpus=2"` keep usage inside the 2-thread budget.
|
|
||||||
|
```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 <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`.
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2026 Stan Grams <sjg@haxx.space>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#
|
||||||
|
# Per-instance settings for an act_runner OpenRC service.
|
||||||
|
# Copy to /etc/conf.d/<service-name>, 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"
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
# SPDX-FileCopyrightText: 2026 Stan Grams <sjg@haxx.space>
|
||||||
|
# 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}"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user