/ephemeral-github-runner

An attempt at a "proper" ephemeral GitHub self-hosted runner.

Primary LanguageShellMIT LicenseMIT

A "proper" ephemeral GitHub self-hosted runner

GitHub allows for self-hosted runners to be deployed, however one of the drawbacks has been the fact that after a build there is the potential for leftovers to be present.

This recipe wraps the GitHub actions/runner into a container that launches the runner inside a QEMU-based VM, executing a single job then terminating. This VM is then repeatedly launched in a loop, so that each job is executed on a brand new VM instance. Internally, the VM downloads a copy of the actions/runner binaries on startup, registers itself as an ephemeral self-hosted runner, and waits for a job.

Organisation-level runners are not yet supported.

docker compose

There is a docker-compose-direct.yml which shows how to configure and run the runner VM in "direct" mode, which has unrestricted network access.

There is a docker-compose-proxied.yml which shows how to configure and run the runner VM in "proxied" mode which funnels external traffic through a preconfigured squid proxy container, limiting the domains the runner has access to.

GitHub Actions Runner Container

$ docker pull ghcr.io/tzarc/ephemeral-github-runner:latest

There are a handful of environment variables that are required in order to actually get the runner talking:

Environment Variable Format Description
NUM_CPUS 1 The number of CPUs to assign to the QEMU VM.
MEMORY_ALLOC 1024 The number of MB to assign to the QEMU VM.
NICE_VAL (optional) 19 The nice value to set the QEMU process to. Defaults to 0.
RUNNER_ARCH (optional) x64 The architecture of the runner to download. Accepts the arch in the release url -- x64, arm64, arm. Defaults to x64.
GITHUB_REPOSITORY owner/repo The repository to attach the self-hosted runners to.
GITHUB_TOKEN As generated by GitHub A fine-grained personal access token, with R/W Administration access to the GITHUB_REPOSITORY.
http_proxy (optional) http://squid:3128 Proxy to use for any HTTP requests.
https_proxy (optional) http://squid:3128 Proxy to use for any HTTPS requests.
no_proxy (optional) hostA,hostB Hosts to bypass for outbound HTTP[S] requests. Not recommended to be used due to inconsistency between apps using it.

Building the container

make container

This will create a tagged container called github-runner-vm:latest.

Squid Container

$ docker pull ghcr.io/tzarc/ephemeral-github-runner:latest-squid

This is a simple squid container that is used to proxy outbound HTTP[S] requests from the runner VM. It allows for configuration of allowed domains:

Environment Variable Format Description
ALLOWED_DOMAINS_LIST .domain-a.com .domain-b.com The allowed domains. Space-separated, should include leading ..
MEM_CACHE_SIZE 1024 Cache size in MB to keep resident in memory.
FILE_CACHE_SIZE 1024 Cache size in MB to keep on disk.
FILE_MAX_SIZE 1024 The maximum size MB of any one file.

Building the container

If you also want to build the squid container:

make squid-container

...which results in a tagged container called github-runner-squid:latest.