🌈🌈🌈 Multi self-hosted GitHub action runners on single host! 🌈🌈🌈
This application is designed for controlling multi self-hosted GitHub Action runners on single host, when Actions Runner Controller (ARC) is not feasible in your engineering environment. This application has following advantages:
- Single Linux host required.
- Single Bash script.
- Lightweight wrapper of GitHub official self-hosted runner.
- Both github.com and GitHub Enterprise are support.
- Either organization or repository or GitHub Cloud Enterprise level runners are supported.
mr.bash - https://github.com/vbem/multi-runners
Environment variables:
MR_GITHUB_BASEURL=https://github.com
MR_GITHUB_API_BASEURL=https://api.github.com
MR_RELEASE_URL=<latest on github.com/actions/runner/releases>
MR_USER_BASE=<default in /etc/default/useradd>
MR_GITHUB_PAT=***
Sub-commands:
add Add one self-hosted runner on this host
e.g. ./mr.bash add --org ORG --repo REPO --labels cloud:ali,region:cn-shanghai
e.g. ./mr.bash add --org ORG --count 3
del Delete one self-hosted runner on this host
e.g. ./mr.bash del --user runner-1
e.g. ./mr.bash del --org ORG --count 3
list List all runners on this host
e.g. ./mr.bash list
download Download GitHub Actions Runner release tar to /tmp/
Detect latest on github.com/actions/runner/releases if MR_RELEASE_URL empty
e.g. ./mr.bash download
pat2token Get runner registration token from GitHub PAT (MR_GITHUB_PAT)
e.g. ./mr.bash pat2token --org SOME_OWNER --repo SOME_REPO
Options:
--enterprise GitHub Cloud Enterprise name, optional
--org GitHub organization name
--repo GitHub repository name, registration on organization-level if empty
--user Linux local username of runner
--labels Extra labels for the runner
--group Runner group for the runner
--token Runner registration token, takes precedence over MR_GITHUB_PAT
--dotenv The lines to set in runner's '.env' files
--count The number to add or del, optional, defaults to 1 for add and all for del
--opts Extra options for 'config.sh', optional, such as '--no-default-labels'
-h --help Show this help.
This application requires to be run under a Linux user with non-password sudo permission (e.g., %runners ALL=(ALL) NOPASSWD:ALL
). It's also fine to run this application by root
:
git clone https://github.com/vbem/multi-runners.git
cd multi-runners
./mr.bash --help
This application requires a GitHub personal access token with smallest permissions and shortest expiration time. Only add
/del
/pat2token
sub-commands need this PAT. You can remove it on GitHub after multi-runners' setup.
PAT types | Repository level runners | Organization level runners |
---|---|---|
Fine-grained PAT (recommended) | Referring to repository API, the administration:write permission is required. |
Referring to organization policy & organization API, the organization_self_hosted_runners:write permission is required. |
Classic PAT | Referring to repository API, need the repo scope |
Refer to organization API, need the admin:org scope; if the repository is private, repo scope is also required. |
During runtime, you can set your PAT in environment variable MR_GITHUB_PAT
. To simplify subsequent execution, you can define any environment variable in .env
file. For example,
# .env file under the directory of this application
MR_GITHUB_PAT='github_pat_***********'
ALL_PROXY=socks5h://localhost
You can run following command to check whether or not your PAT can generate GitHub Actions runners' registration-token:
./mr.bash pat2token --org <ORG-NAME> --repo <REPO-NAME>
If environment variable MR_RELEASE_URL
is empty, this application will download the latest version of GitHub Actions runners tar package to local directory /tmp/
during runtime.
./mr.bash download
If your Linux host is internet bandwidth limited, you can also manually upload it from laptop to /tmp/<tar.gz file name>
, and set the MR_RELEASE_URL
env in .env
file, e.g. /tmp/actions-runner-linux-x64-2.345.6.tar.gz
.
GitHub Enterprise Server editions usually have different server and API URL prefixes comparing with github.com, you can set them in environment variables MR_GITHUB_BASEURL
and MR_GITHUB_API_BASEURL
.
For GitHub Enterprise Cloud level registration, you can specify the --enterprise
option to set the GitHub Enterprise Cloud name.
To setup multi-runners, you can simplify run following command multi times:
# 1 runner for repository `<ORG-NAME-1>/<REPO-NAME-1>`
./mr.bash add --org <ORG-NAME-1> --repo <REPO-NAME-1>
# 2 runners for repository `<ORG-NAME-1>/<REPO-NAME-2>`
./mr.bash add --org <ORG-NAME-1> --repo <REPO-NAME-2> --count 2
# 3 runners for organization `<ORG-NAME-2>`
./mr.bash add --org <ORG-NAME-2> --count 3
This application will create one Linux local user for one runner via useradd
command. The Base Directory of these users is read from HOME
setting in your /etc/default/useradd
file by default (typically /home
). You can also set it in environment variable MR_USER_BASE
to override system-wide default.
This application also integrated status check of runners.
./mr.bash list
Which outputs,
runner-0 537M running https://github.com/<ORG-NAME-1>/<REPO-NAME-1>
runner-1 537M running https://github.com/<ORG-NAME-1>/<REPO-NAME-2>
runner-2 537M running https://github.com/<ORG-NAME-1>/<REPO-NAME-2>
runner-3 537M running https://github.com/<ORG-NAME-2>
runner-4 537M running https://github.com/<ORG-NAME-2>
runner-5 537M running https://github.com/<ORG-NAME-2>
# delete an existing runner by its local Linux username.
./mr.bash del --user <runner-?>
# delete all runners for specific repository
./mr.bash del --org <ORG-NAME-1> --repo <REPO-NAME-2>
# delete multi runners by `--count` options.
./mr.bash del --org <ORG-NAME-2> --count 2
In jobs.<job_id>.runs-on
, target runners can be based on the labels as follows via GitHub context:
# For organization level self-hosted runners
runs-on: [self-hosted, '${{ github.repository_owner }}']
# For repository level self-hosted runners
runs-on: [self-hosted, '${{ github.repository }}']
As described in GitHub official document, there's an approach to inject environment variables into runners process via the .env
file before configuring or starting the self-hosted runners. This can be achieved via the --dotenv
option, for example:
./mr.bash add --org <ORG> --repo <REPO> --dotenv 'TZ=Asia/Shanghai' --dotenv 'PATH=\$PATH:/mybin' --dotenv 'all_proxy=socks5h://localhost:1080'
Then the following lines will be added to .env
file located in self-hosted runner's directory before its configuring and starting:
TZ=Asia/Shanghai
PATH=$PATH:/mybin
all_proxy=socks5h://localhost:1080