Set up the GitHub self-hosted runner
The github-runner-01 container (192.168.10.111) runs the workflows that need access to the LAN: OpenTofu plans and applies against Proxmox and Hyperion, and the LXC bootstrap jobs. Those jobs run inside the brsalcedom/homelab-ci image, so the runner needs Docker.
This guide is for Debian 13. On another OS, follow the official Docker install docs for step 2.
Prerequisites
Section titled “Prerequisites”- The
github-runner-01container is deployed (see Deploy LXC containers). - The SSH private key set when the container was created.
- Admin access to the repository on GitHub, to get a registration token.
Connect as root:
ssh -i ~/.ssh/id_ed25519 root@192.168.10.111Steps 1 to 3 run as root without sudo.
1. Install base packages
Section titled “1. Install base packages”apt updateapt install -y curl git sudo ca-certificates2. Install Docker
Section titled “2. Install Docker”install -m 0755 -d /etc/apt/keyringscurl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.ascchmod a+r /etc/apt/keyrings/docker.asc
tee /etc/apt/sources.list.d/docker.sources <<EOFTypes: debURIs: https://download.docker.com/linux/debianSuites: $(. /etc/os-release && echo "$VERSION_CODENAME")Components: stableSigned-By: /etc/apt/keyrings/docker.ascEOF
apt updateapt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
docker run hello-world3. Create the runner user
Section titled “3. Create the runner user”The runner must not run as root.
useradd -m -s /bin/bash githubusermod -aG docker githubusermod -aG sudo github4. Download and register the runner
Section titled “4. Download and register the runner”Switch to the new user:
su - githubmkdir -p ~/actions-runner && cd ~/actions-runnerDownload the runner. Replace 2.331.0 with the latest version from the runner releases page, and check the hash published there:
curl -o actions-runner-linux-x64-2.331.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.331.0/actions-runner-linux-x64-2.331.0.tar.gzecho "<hash> actions-runner-linux-x64-2.331.0.tar.gz" | sha256sum -ctar xzf ./actions-runner-linux-x64-2.331.0.tar.gzGet a registration token in GitHub under Settings → Actions → Runners → New self-hosted runner, then:
./config.sh --url https://github.com/Brsalcedom/homelab-iac --token <TOKEN>Accept the defaults, except the runner name: use github-runner-01.
5. Install the runner as a systemd service
Section titled “5. Install the runner as a systemd service”Go back to root (exit) and run:
cd /home/github/actions-runnersudo ./svc.sh install githubsudo ./svc.sh startsudo ./svc.sh statusThe service name is actions.runner.<owner>-<repo>.<runner>.service, here actions.runner.Brsalcedom-homelab-iac.github-runner-01.service. Enable it at boot:
sudo systemctl enable actions.runner.Brsalcedom-homelab-iac.github-runner-01.service6. Verify
Section titled “6. Verify”- In GitHub, Settings → Actions → Runners shows
github-runner-01as Idle. - Run any
workflow_dispatchworkflow (for exampleTofu :: Proxmox VM) and check that the runner picks it up.
Operate the runner
Section titled “Operate the runner”cd /home/github/actions-runnersudo ./svc.sh stopsudo ./svc.sh startsudo ./svc.sh uninstall
# Service logssudo journalctl -u actions.runner.Brsalcedom-homelab-iac.github-runner-01.service -f
# Runner logssudo -u github tail -f /home/github/actions-runner/_diag/*.logUpdate the runner
Section titled “Update the runner”cd /home/github/actions-runnersudo ./svc.sh stopsudo -u github curl -o actions-runner-linux-x64-<VERSION>.tar.gz -L https://github.com/actions/runner/releases/download/v<VERSION>/actions-runner-linux-x64-<VERSION>.tar.gzsudo -u github tar xzf ./actions-runner-linux-x64-<VERSION>.tar.gzsudo ./svc.sh startTroubleshooting
Section titled “Troubleshooting”| Symptom | Check |
|---|---|
| Runner doesn’t appear in GitHub | systemctl status and journalctl -n 50 for the service |
| Docker permission denied in jobs | groups github must include docker; if not, usermod -aG docker github and restart the service |
| Runner shows Offline | Connectivity to github.com, then restart the service |
Security notes
Section titled “Security notes”- The
githubuser can reach the Docker socket and its work directory~/actions-runner/_work. - Secrets come from GitHub Secrets and from Bitwarden Secrets Manager (
bitwarden/sm-action). Never store secrets on the container. - Watch CPU, RAM and disk usage of the container; container jobs and images add up.