GitHub Self-Hosted Runners Part 2: It's Raining Tokens!
Paying with our Token
NOTE: If you followed Part 1, I have recently edited and fixed the included Dockerfile. The main issue was that I made it using Alpine (now amended to Debian) as I wanted the lightest distribution for a builder. In my haste I did not check that GH Runner is still not available for Alpine distros. The other issue is as the end of the file as the CMD instruction was using a list of parameters instead of a single string. This does not allow for variable replacement as it is never passed to a shell within the container. Sorry for this.
Testing
The easiest way to test that we can register a self-hosted runner is to use the GUI to create a new token. This is good enough for a test, but not too useful for a fully automated setup. In order to do the test, go to one of your personal repositories (or one where you have administrator/ownership status) and select Settings > Actions > Runners. This should bring up a new screen with an option for `New Self-Hosted Runner.`
In here we can see the options as to how to install the runner package in several Operating Systems, but our docker image takes care of that. Instead we will focus on the second part: Configure. Here we will find a URL (one like https://github.com/{your_username}/{your_repo}) as well as a token. This token is a 1-hour token that allows you to register any number of runners to this repository or organization. You can finally run a test-drive with your container using these two as follows:
docker build ./ --tag runner_test:latest --build-arg TOKEN=${mytoken} --build-arg GH_URL=${my_gh_url}
# Now to run and let it register itself
docker run -d runner_test:latest
If you wait about a minute, your list of self-hosted runners should now show one new runner. This is specially registered as an ephemeral runner (it's one of the flags passed to the registration in the CMD instruction in the Dockerfile) which means that as soon as it's done servicing one job it will shut down.
领英推荐
In search of tokens
Manually getting tokens from the GUI every hour or so is not a very scalable process. One potential solution is to fetch a new token using GitHub's API, but for this you need authentication with the Repository Administration permission (or similar permission for Organization and Enterprise level runners.) One way of doing this is with a Personal Access Token (PAT) that you can create for your personal user and giving it limited permissions for only this use case.
For this, head into your account Settings > Developer Settings > Personal Access Token > Fine-grained Tokens.
Here you will create a new token that has access to your repo (ideally, specify explicitly which repository it is in Only Select Repositories) and you will need to add ?Repository Permissions > Administration > Read and Write. Once you create it, it will show you the token only one time (make sure you copy it to a safe place) and leave the screen.
Testing this token
We can finally test this token with a simple curl command:
curl -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer {your_token_here}" \
https://api.github.com/repos/{your_username}/{your_repo}/actions/runners/registration-token
Should everything be going well, we will receive a JSON response with our token and expiration date about 1 hour in the future. This token you can use to rebuild your Dockerfile and register a runner.
Issues with this approach
Ideally, we want to do this curl on start of the Docker container, which we are not yet doing. We need to be careful with where we store our PAT (for example, use GitHub secrets when using it in a live repo instead of storing it in plaintext.) The additional problem for this is that, except for personal repositories, you should not use a PAT (again, PERSONAL access token) for ORG or Enterprise authentication of an automated tool. For that we will use GitHub Apps and JWT authentication, but that will certainly be for Part 3.
Solution Architect at STMicroelectronics
1 年I'm interested to know when Part 3 of the article will be released. Thank you for the article, it was well done!
Cloud Infrastructure Engineer Principal at Dayforce
1 年Curious when part 3 will be out, currently looking into using a github app to create runners at the org level using a cloud-init file. Thanks for the article, great job.