110 lines
3.8 KiB
Markdown
110 lines
3.8 KiB
Markdown
# cargoxx-pkgs runner
|
|
|
|
Self-hosted Gitea Actions runner that validates package PRs.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
+----------------+ +-------------------+ +--------------------+
|
|
| Gitea instance | <----> | act_runner | -----> | job container |
|
|
| (queues jobs) | poll | (this docker- | docker| cargoxx-runner- |
|
|
| | | compose service) | spawn | job:latest |
|
|
+----------------+ +-------------------+ +--------------------+
|
|
```
|
|
|
|
- `compose.yml` runs the official `gitea/act_runner:nightly` image,
|
|
which polls Gitea for jobs and spawns one container per workflow
|
|
run via the host's Docker socket.
|
|
- `flake.nix` builds the **job container image** — reproducible,
|
|
declarative, ships `nix`, `git`, `curl`, `jq`, `tea`, and a
|
|
single-user `NIX_CONFIG`. This image runs the actual workflow
|
|
steps; act_runner just orchestrates it.
|
|
- `config.yaml` maps `runs-on: self-hosted` (from
|
|
`.gitea/workflows/*.yml`) to the job image.
|
|
|
|
## One-time setup
|
|
|
|
1. **Build + load the job image** into the host's Docker daemon:
|
|
|
|
```sh
|
|
cd runner
|
|
nix run --extra-experimental-features 'nix-command flakes' .#load-image
|
|
```
|
|
|
|
Re-run whenever you bump nixpkgs or change the tool list.
|
|
|
|
2. **Mint a runner registration token** in the Gitea UI:
|
|
`Site Administration → Actions → Runners → Create new Runner`.
|
|
Copy the token.
|
|
|
|
3. **Provision the `.env`** alongside `compose.yml`:
|
|
|
|
```env
|
|
GITEA_INSTANCE_URL=https://git.amadey.xyz
|
|
GITEA_RUNNER_REGISTRATION_TOKEN=<paste here>
|
|
GITEA_RUNNER_NAME=cargoxx-pkgs-runner
|
|
GITEA_RUNNER_LABELS=self-hosted
|
|
```
|
|
|
|
4. **Generate the binary-cache signing key** + cache directory. The
|
|
workflow's "push to binary cache" step writes here; nginx (or
|
|
anything you point at it) serves it back over HTTPS to consumers.
|
|
|
|
```sh
|
|
mkdir -p cache/store
|
|
nix-store --generate-binary-cache-key \
|
|
cache.cargoxx.<your-domain> \
|
|
cache/cache.sec cache/cache.pub
|
|
chmod 600 cache/cache.sec
|
|
```
|
|
|
|
The `cache/` directory is gitignored. Both keys live alongside
|
|
`compose.yml`; the named volume binds use `${PWD}/cache/...`.
|
|
|
|
5. **Pick the Caddy ports.** `compose.yml` runs Caddy alongside the
|
|
runner to HTTPS-front the cache. Because the router does PAT, the
|
|
*internal* ports Caddy listens on must equal whatever 80/443 are
|
|
forwarded to. Add to `.env`:
|
|
|
|
```env
|
|
CADDY_HTTP_PORT=8080
|
|
CADDY_HTTPS_PORT=8443
|
|
```
|
|
|
|
Both compose.yml and the Caddyfile pick those up. The Caddyfile
|
|
already targets `cache.cargoxx.amadey.xyz` and the e-mail
|
|
`vorontsov@amadey.xyz`; edit if you're deploying somewhere else.
|
|
|
|
ACME provisioning works as long as the router forwards 80 →
|
|
CADDY_HTTP_PORT and 443 → CADDY_HTTPS_PORT, so Let's Encrypt's
|
|
HTTP-01 challenge reaches Caddy.
|
|
|
|
Consumers' substituter config (`substituters = https://cache.<domain>`,
|
|
`trusted-public-keys = <cache.pub>`) is baked into cargoxx's own
|
|
wrapper (`cargoxx/flake.nix:cargoxxNixConfig`), so any installed
|
|
`cargoxx` binary picks them up — no per-user setup needed.
|
|
|
|
6. **Start the runner**:
|
|
|
|
```sh
|
|
docker compose up -d
|
|
docker compose logs -f runner
|
|
```
|
|
|
|
First boot registers the runner with Gitea; subsequent boots reuse
|
|
the persisted token in `./data/.runner`.
|
|
|
|
## Updating
|
|
|
|
- Change a workflow step's tools → edit `flake.nix`, rerun
|
|
`nix run .#load-image`.
|
|
- Bump nixpkgs → `nix flake update` in this dir, rebuild the image.
|
|
- act_runner itself updates by `docker compose pull && docker compose up -d`.
|
|
|
|
## Why not host mode?
|
|
|
|
Host mode (act_runner running workflows directly on the host) would
|
|
save the Docker indirection but tightly couples the runner host to
|
|
the toolchain. Docker mode lets us treat the job image as a
|
|
deployable artifact — same image on every runner, no drift.
|