feat(homelab): isolate PR runner and add Paperless
This commit is contained in:
1 parent
e3ae86cd01
commit
563e4c2244
19 files changed
+581
-42
No files matched your search
+51
-20
@@ -1,10 +1,13 @@
|
||||
# Homelab CI/CD
|
||||
|
||||
The native Gitea runners run on **vps**; production runs on **workstation**.
|
||||
Main-branch checks and image builds use `homelab:host`. Pull request and
|
||||
non-main checks use `homelab-pr:host` under a separate account without Docker
|
||||
access. The `homelab-pr` runner is registered at User scope for `forust`, so
|
||||
any repository under that account can schedule jobs that request this label.
|
||||
Main-branch checks and image builds use `homelab:host`. Pull request checks use
|
||||
`homelab-pr` in a Docker job container. CI PR checks use `pull_request_target`,
|
||||
so Gitea loads the workflow from the trusted base branch. That event then runs
|
||||
untrusted PR code, so the workflow must select `homelab-pr` before checkout and
|
||||
must not expose secrets. The CI validation jobs grant only `contents: read` and
|
||||
checkout the explicit PR head SHA with `persist-credentials: false`. Register
|
||||
`homelab-pr` at repository scope so only this repository can schedule its jobs.
|
||||
Each runner accepts one job at a time; the build waits for every check to pass.
|
||||
CI and deploy runs also show a summary with
|
||||
the release SHA, image build or reuse results, deploy mode, selected services,
|
||||
@@ -42,29 +45,57 @@ Nothing runs `docker system prune`, removes unrelated images, or deletes volumes
|
||||
|
||||
### Pull request runner
|
||||
|
||||
Install the unprivileged host runner on the VPS:
|
||||
Install the PR container runner on the VPS:
|
||||
|
||||
```sh
|
||||
sudo bash .gitea/runner/setup-pr-runner.sh
|
||||
```
|
||||
|
||||
Get a registration token from the user Actions runner settings. Run the
|
||||
installer in a terminal. It asks for the token without echoing it, registers the
|
||||
runner as `homelab-pr` with label `homelab-pr:host`, then enables the service.
|
||||
The work directory is `/var/lib/gitea-pr-runner`. Confirm that Gitea lists the
|
||||
runner as User scope before merging the workflow change. An unmatched label can
|
||||
fall back to the default job image.
|
||||
Create a runner registration token from this repository's Actions runner
|
||||
settings. Run the installer in a terminal. It asks for the token without
|
||||
echoing it and registers `homelab-pr` with label
|
||||
`homelab-pr:docker://docker.gitea.com/runner-images:ubuntu-24.04-v26.09.01`. Confirm that
|
||||
Gitea lists the runner at Repository scope. The service runs as
|
||||
`gitea-pr-runner`; systemd grants that service access to the Docker socket with
|
||||
`SupplementaryGroups=docker`. Keep the account itself out of the `docker`
|
||||
group. The work directory is `/var/lib/gitea-pr-runner`.
|
||||
|
||||
Renovate PR validation uses `pull_request_target`, which reads the workflow from
|
||||
the base branch. It checks out the PR head only after runner selection and runs
|
||||
that code on `homelab-pr`. Keep this workflow read-only and do not add secrets.
|
||||
The runner config disables privileged containers, forbids workflow volume
|
||||
mounts, and prevents the Docker socket from being mounted into job and action
|
||||
containers. Do not mount the runner home or its host-side tool cache into a job.
|
||||
The existing host-side cache is retained, but PR job containers cannot read it.
|
||||
An unmatched label can fall back to the default job image; check the registered
|
||||
label before enabling PR checks.
|
||||
|
||||
The PR runner has a separate home and tool cache. Do not add it to the `docker`
|
||||
group or give it access to `/var/run/docker.sock`. It runs repository code from
|
||||
pull requests, so keep its registration and permissions separate from the
|
||||
trusted `homelab` runner. This separates users and host permissions, but both
|
||||
runners still share the VPS kernel and network. Use a disposable VM if PRs from
|
||||
untrusted external authors must be fully isolated.
|
||||
The installer reuses `/var/lib/gitea-pr-runner/.runner` when it exists. That
|
||||
file keeps the registration scope assigned by Gitea. To move an existing
|
||||
User-scoped runner to Repository scope, stop the service, remove the old runner
|
||||
from Gitea, back up and remove that registration file, then run the installer
|
||||
with a token created in this repository's Actions runner settings. Confirm the
|
||||
new scope in Gitea before enabling PR checks.
|
||||
|
||||
The CI and Renovate workflows use `pull_request_target`, which reads the
|
||||
workflow from the base branch. They select `homelab-pr` before checking out PR
|
||||
code. The explicit head SHA and `persist-credentials: false` are mandatory:
|
||||
without the latter, checkout can leave the job token in Git configuration.
|
||||
Keep PR validation read-only and do not add Actions secrets. In the checked-in
|
||||
workflows, only a push to `main` or a manual CI run on `main` can select the
|
||||
trusted `homelab` runner. Gitea schedules jobs by matching `runs-on` labels; the
|
||||
runner does not restrict jobs by event or branch. Keep Gitea's approval gate for
|
||||
fork PR workflows enabled. Verify the live Gitea version and approval setting
|
||||
before relying on this gate; the image tag in the repository does not prove the
|
||||
version currently running. Before approving a fork workflow run, review all new
|
||||
and changed workflow files: a PR-defined `pull_request` workflow can request
|
||||
the `homelab` label. Automatic CI and Renovate PR checks use the trusted base
|
||||
workflow and select only `homelab-pr`. The release and deploy jobs stay on the
|
||||
trusted runner.
|
||||
|
||||
The runner service can access the host Docker daemon, but job and action
|
||||
containers do not receive its socket or arbitrary host mounts. The runner and
|
||||
job containers still share the VPS kernel and Docker daemon. A container escape
|
||||
can therefore affect the host and other workloads. This is container isolation,
|
||||
not VM isolation; use disposable VMs for PRs that require a separate kernel and
|
||||
Docker daemon.
|
||||
|
||||
## Workstation setup
|
||||
|
||||
|
||||
Reference in new issue
Block a user