A dead-simple way to add GitHub Actions Runners to your account.
I kept getting annoyed by how the GitHub Actions runner script is sort of stateful and has access to the surrounding environment. What I really want is the exact same as the GitHub Actions default runner but self-host it. This is in that direction. The actions container is torn down and restarted when the action ends, therefore it's stateless like the default runner.
Additionally, if you have a powerful machine available to you and want to use that as a runner so you don't have to pay for a third- party service to use what resources you already have available.
- Stateless execution
- Container isolation
- Self-host it wherever you want
- Architecture emulation via QEMU
- There's no dispatching layer so you'll pay more than something like runs-on if that's your jam.
Bring up the container, setting ACCESS_TOKEN
and ORG
.
docker run -e ORG=... -e ACCESS_TOKEN=... -d --rm --restart always ghcr.io/wponline/docker-gha-runner:main
Once it's running, check out your runners page:
You can then update your GitHub Actions workflows:
jobs:
build:
runs-on: [self-hosted, linux]
Using docker compose
allows some additional cool features such as adding replicas.
Create a docker-compose.yml
services:
runner:
image: ghcr.io/wponline/docker-gha-runner:main
restart: always
deploy:
mode: replicated
replicas: 4
environment:
ORG: <the org name you wish to link to>
ACCESS_TOKEN: <github access token>
Then
docker compose up -d
If you want to emulate a different platform (such as an arm64 machine on an x86-64 machine), first make sure you've configured qemu
docker run --rm --privileged multiarch/qemu-user-static --reset --persistent yes --credential yes
Then, set platform
in your compose file:
services:
runner_amd64:
image: ghcr.io/wponline/docker-gha-runner:main
platform: linux/amd64
restart: always
deploy:
mode: replicated
replicas: 4
environment:
ORG: <the org name you wish to link to>
ACCESS_TOKEN: <github access token>
runner_arm64:
image: ghcr.io/wponline/docker-gha-runner:main
platform: linux/arm64
restart: always
deploy:
mode: replicated
replicas: 4
environment:
ORG: <the org name you wish to link to>
ACCESS_TOKEN: <github access token>
And you should now have four x86-64 runners and four arm64 runners. Neat!
Some example compose files are available to demonstrate how to use this Docker-based GitHub Actions runner
with Docker-based GitHub Actions (ex. docker/build-push-action
), a form of Docker-in-Docker.
This version is more secure but has some limitations, notably it does not support platform emulation due to binfmt_misc support in Sysbox. It also requires Sysbox to be installed on the host running the Actions runners, which has certain Linux distro limitations.
To use this version, make sure your host meets the requirements and install Sysbox on the host. Use the example
compose file, or specify the sysbox-runc
runtime and set the environment variable DOCKER_SYSBOX_RUNTIME
to
a non-empty string (ex. 1
or true
) in your own compose file.
This version is insecure. Docker containers can access the host. TLS is enabled on the Docker daemon to minimize network exposure to rogue clients. Make sure you trust the Actions jobs that can be executed on these runners, including pull requests!
This version is more flexible than the Sysbox-based DinD solution and supports platform emulation. It works by spawning Docker as a separate service (a sidecar) and setting the appropriate environment variables to enable communication from the runners. This version requires no extra configuration and should work "out of the box."
docker exec -t gha-runner-gha-runner-arm64-1 docker run --rm -t arm64v8/ubuntu uname -m
aarch64
This version is the same as DinD with a sidecar
except it has platform
emulation support removed. This does not make it any more secure. But, you can use this version if you do not
need platform emulation support and your host lacks support for Sysbox,
or you don't want to install it.