Hosting your own ubuntu github action runner

Github actions are really cool, the workflow syntax is easy to grok and there are tonnes of pre-built actions out there you can used to build your code. The free tier is a little limited on the number of hours you get. If you’re stuck trying to debug a deployment or build issue that doesn’t happen locally you can easily burn them all

Assuming you already have a server or instance with Ubuntu 20.04 on it:

First you need to install the pre-requisite packages

sudo apt install build-essential \
    crossbuild-essential-arm64 \
    debootstrap debhelper \
    jq \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

Next we need docker, see the guide here for details

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
sudo apt install docker-ce

You need to give the user that will run the github actions the docker group too

sudo usermod -aG docker ${USER}
su - ${USER}

Next we need a new and shiny version of git

sudo add-apt-repository ppa:git-core/ppa
apt-get update
apt-get install git

Now the file system for the actions runner needs to be setup

mkdir -m 777 ~/actions-runner
https://github.com/actions/runner/releases/download/v2.283.3/actions-runner-linux-x64-2.283.3.tar.gz
tar -xf v2.283.3/actions-runner-linux-x64-2.283.3.tar.gz --directory actions-runner

At this point we’re ready to start our runner up. You will need a PAT from github to do this. Follow the guide here and make sure the token has the following permissions:

admin:enterprise, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, notifications, repo, workflow, write:packages

grab the token and stick it in an environment variable for now

export github_token="thisisatesttokenuseyouronefromthelaststep"

I’m going to call this instance build-runner-1 because I’m lazy and just call things what they do. This is important because the runner will be registered in github under that name. For repeatability sake, if you are redeploying, grab the details of the instance you are overwriting:

export existing_runner_id=$(curl -v -H "Authorization: token $github_token" \
      -H "Accept: application/vnd.github.v3+json" \
      -s \
      https://api.github.com/orgs/albeego/actions/runners 2>/dev/null \
      | jq 'try .runners[] | select(.name == "build-runner-1") | .id')

And clear it down if there is one

curl -v -H "Authorization: token $github_token" \
      -X DELETE \
      -H "Accept: application/vnd.github.v3+json" \
      -s \
      https://api.github.com/orgs/albeego/actions/runners/$existing_runner_id 2>/dev/null

Next we need to grab a new runner token, this token is specific to the runner being created. You can re-use them if you keep a note of them. I prefer to just nuke and pave and keep an access token instead for automation

export new_runner_token=$(curl -v -H "Authorization: token $github_token }}" \
      -X POST \
      -H "Accept: application/vnd.github.v3+json" \
      -s \
      https://api.github.com/orgs/albeego/actions/runners/registration-token 2>/dev/null \
      | jq .token

And configure your runner

cd actions-runner
./config.sh --url https://github.com/albeego --token $new_runner_token --labels build-runner

You will probably want to install the runner as a systemd service, it means it will start up again if you reboot. Just run the included script from the actions-runner directory

./svc.sh install

Now we need to make sure that the systemd unit has access to docker too, this will give you issues if you dont do it with the docker command not being available to the runner. Find the unit file and edit it

/etc/systemd/system/actions.runner.[organisation or username].build-runner-1.service

After the User=ubuntu line add Group=docker

Now just reload the service daemon and start the service

sudo systemctl daemon-reload
./svc.sh start

You should now be able to see the runner in the github UI. You can add any additional packages to the runner instance, this can save your builds some precious time by avoiding downloading containers with the tools in or updating them and it gives you a bit of configuration control over the tools in use. Don’t forget to keep them up to date though!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: