https://github.com/kekyo/ga_runner
GitHub Actions Self-hosted immutable runner
https://github.com/kekyo/ga_runner
github immutable podman self-hosted-runner
Last synced: 10 months ago
JSON representation
GitHub Actions Self-hosted immutable runner
- Host: GitHub
- URL: https://github.com/kekyo/ga_runner
- Owner: kekyo
- License: mit
- Created: 2025-03-06T06:58:02.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2025-03-07T08:11:08.000Z (10 months ago)
- Last Synced: 2025-03-07T08:28:53.999Z (10 months ago)
- Topics: github, immutable, podman, self-hosted-runner
- Language: Shell
- Homepage:
- Size: 141 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# GitHub Actions Self-hosted immutable runner
[](https://www.repostatus.org/#wip)
This is still work in progress.
Tested Actions runner version: [2.322.0](https://github.com/actions/runner/releases) [2025/3/6]
----
[](https://github.com/kekyo/ga_runner/blob/main/README_ja.md)
## What is this?
GitHub Actions self-hosted runners are convenient, but have you ever thought about running them in an immutable way?
The runners hosted by GitHub are immutable, and are destroyed each time a build is run,
so you can assume a clean build environment.
However, because self-hosted runners cannot directly mimic this behavior,
it is quite troublesome to set up a clean build environment.
This script configures GitHub Actions self-hosted runners to run immutably.
It is very easy to use, and the prepared runner instance is reset each time a job is executed, which improves the reproducibility of CI/CD.
## How it works
This script has been tested on Ubuntu 24.04 host
(it is probably also compatible with recent Ubuntu and Debian, but this has not been tested).
And the runner runs based on [Ubuntu 24.04 docker image](https://hub.docker.com/_/ubuntu/).
The script installs [`podman` (an OSS implementation compatible with Docker)](https://podman.io/)
and builds a self-hosted runner instance on a container.
When the runner finishes executing the job, this container also terminates,
the container is deleted on the spot, and the container is executed again.
`podman` runs as the superuser, but runs as a normal user inside the container (you can also use `sudo`).
This series of actions is registered as a `systemd` service,
so once the host OS starts up, everything is handled automatically.
In other words, as the administrator of the host machine, you don't have to do anything! ...maybe ;)
## How to use it
The script has `sudo` inserted appropriately, so you can start working as a normal user.
We will explain the repository that wants to install the self-hosted runner as `https://github.com/kekyo/foobar`:
1. Clone `ga_runner` repository on your host machine:
```bash
$ git clone https://github.com/kekyo/ga_runner
```
2. Build `podman` image (You have to run only once per the host).
It will be installed `curl` and `podman` automatically:
```bash
$ cd ga_runner
$ ./build.sh
```
3. Pick your repository "Actions runner token" from GitHub.
It is NOT "personal access token":


4. Install runner service by:
`install.sh `. For example:
```bash
$ ./install.sh kekyo foobar ABP************************
```
Done!
The `systemd` service is named as `github-actions-runner_kekyo_foobar`.
Therefore, to check the service in operation:
```bash
$ sudo systemctl status github-actions-runner_kekyo_foobar
```
Please be careful: The Git local repository contains scripts that are referenced by `systemd`,
so it is necessary to keep it even after installation.
## Storing configuration information
When runner access GitHub for the first time, you will be authenticated using your "Actions runner token".
The results of this authentication will be stored in the `scripts/runner-cache/config/` directory.
If something goes wrong, delete the subdirectories for each service stored in this directory.
Authenticate again using your "Actions runner token".
If the "Actions runner token" has already expired, authentication will fail.
In this case, delete the service using `remove.sh` and start again from the beginning, obtaining a new "Actions runner token".
## Installed packages on the job container
Minimized package installation:
```bash
apt-get install -y sudo curl libxml2-utils git unzip libicu-dev
```
See [Dockerfile](scripts/Dockerfile) for detail.
If necessary, you can install additional packages using `apt` or other tools within the Actions job YAML script.
## Install multiple runner instance
TODO: WIP
Yes, you can run multiple runner instance on one host OS.
Execute `install.sh` multiple time with different user/repository name.
Even in that case, you only need to run the container image builder (`build.sh`) only once.
## Actions runner package will be cached
The Actions runner try to download latest package version `actions-runner-linux-x64-*.tar.gz`
from official [GitHub Actions runner release repository](https://github.com/actions/runner/releases) each started.
And it will be cached the directory `scripts/runner-cache/` automatically.
When this files are valid to latest, the runner reuse it.
## Redirect HTTP/HTTPS to the proxy server
You may want to cache the HTTP/HTTPS access that the job performs.
These can be redirected to your nearest local proxy server, which will then cache them.
This will speed up the download of packages and content.
The URL to the proxy server is specified as the fourth optional argument to `install.sh`:
```bash
$ ./install.sh kekyo foobar ABP************************ http://proxy.example.com:3128
```
The URL you specify must be a valid hostname that can be accessed from within the runner container.
In other words, please note that `localhost` cannot be used.
### Using squid proxy server
Here is an example configuration for the [`squid` proxy server](https://www.squid-cache.org/) that can be used for this purpose.
This is an example of co-locating `squid` with maximum 1000MB (files each 100MB) disk cache on the machine that hosts `podman`:
```bash
$ sudo apt install squid
$ echo "http_access allow localnet" | sudo tee /etc/squid/conf.d/localnet.conf
$ echo "cache_dir ufs /var/spool/squid 1000 16 256" | sudo tee /etc/squid/conf.d/cache_dir.conf
$ echo "maximum_object_size 100 MB" | sudo tee -a /etc/squid/conf.d/cache_dir.conf
$ sudo systemctl restart squid
```
`podman` can specify the host's virtual network address by using the special `host.containers.internal` FQDN, so you can specify the URL as follows:
```bash
$ ./install.sh kekyo foobar ABP************************ http://host.containers.internal:3128
```
## Remove the runner service
```bash
$ ./remove.sh kekyo foobar
```
----
## TODO
* Supports multiple runner instance on same repository.
* Cache the packages into `runner-cache/` (APT, NPM, NuGet and etc)
## License
MIT