In the fall of 2018, Github launched Actions to the World.

If you are reading this tutorial, it’s likely that you have used GitHub at some point. As such, using GitHub actions is a no-brainer for many users, myself included.

However, the free tier is only so generous, and many organizations have specialized hardware needs like GPUs, a different operating system, or an extra compute that could be better utilized for continuous integration.

In this tutorial, we will take a look at how to host your own GitHub actions runner using Civo.

Prerequisites

This tutorial assumes some familiarity with the Linux operating system. Additionally, you will need the following installed in order to follow along:

Creating a Virtual Machine

We’ll begin by creating a virtual machine using the Civo CLI:

civo instance create --hostname=wonderwoman --size=g3.medium --diskimage=ubuntu-jammy --initialuser=demo

This will spin up a new Ubuntu instance called Deathstar in your default region and create a new user called demo.

Retrieve machine IP

With a machine created, you can now retrieve the public ip using the Civo CLI:

civo instance show -o json wonderwoman | jq .public_ip

Retrieve user password

To connect to the virtual machine, we will also need to retrieve the initial password for the demo user:

civo instance show -o json wonderwoman | jq .initial_password

At this point, you should be able to log in to your machine:

ssh demo@<your instance ip>

Repository Setup

Begin by creating a new repository. If you have the GitHub CLI installed, feel free to use gh repo new; otherwise, head over to repo.new to create one.

Repository Setup with GitHub CLI

Once created, clone the repo to your machine:

git clone <https://github.com/yourusername/repo-name>

Register your instance

Next, we want to register the instance we created as a workflow runner, and head back to your repository. Click on settings > Actions > Runners.

Register your instance initial step

You should see the following page:

Registering your instance output screen

At this point, SSH into the instance you created earlier and run the following commands: Create a folder:

mkdir actions-runner && cd actions-runner

Download the latest runner package:

curl -o actions-runner-linux-x64-2.319.1.tar.gz -L <https://github.com/actions/runner/releases/download/v2.319.1/actions-runner-linux-x64-2.319.1.tar.gz>

Extract the package:

tar xzf ./actions-runner-linux-x64-2.319.1.tar.gz

Configure the Runner

Thankfully, the actions runner comes with a script to perform all the setup required. One thing we will need to add is a flag to insert labels. This is important when you have multiple runners; for instance you might want to add a gpu label for instances with a GPU or arm for your arm-based instances or label to separate runners by cloud, for instance civo.

Within the actions-runner directory, run the following command:

./config.sh --url <your repo URL>  --token <yourtokengoeshere> --labels civo

The important part here is the --labels flag, --token is used to authenticate with GitHub. Your token should be available in the runners section of your repo’s settings page.

Output is similar to:

Configure the Runner

With the runner configured, go ahead and and install the runner as a service:

 sudo ./svc.sh install demo

Output is similar to:

Configuring the Runner output

Start the runner:

sudo ./svc.sh start

Output is similar to:

Part 2 Configuring the Runner output

Now we have the runner installed as a systemD unit, and we can test this with a workflow.

Testing the Runner

Back on your local machine, head to the repository you cloned earlier and add a new workflow using the following commands:

Create a workflow directory:

mkdir -p .github/workflows

Add a workflow:

cat << 'EOF' > .github/workflows/ci.yaml
name: Custom runner

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  build:
    # The type of runner that the job will run on
    runs-on: civo

    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      - name: Run a one-line script
        run: echo Hello, world!
EOF

The important part to note here is that we set job.runs-on to civo, which matches the label we added earlier.

Trigger the build:

git add . && git commit -m"custom" && git push

Head over to the actions tab, and you should see a successful build.

Triggering the build

We can verify the build was indeed processed by the runner we created by running the following command on the instance:

 sudo ./svc.sh status

Output is similar to:

Triggering the build output

Clean up

Upon completing this tutorial, you might want to clean up some of the resources you have created. To delete the instance you created, run the following command:

civo instance rm wonderwoman

If you would like to keep the instance but remove the runner, check out this section of the GitHub docs.

Summary

Self hosted runners are a great way to utilize unused computed or run your CI/CD workflows that require specialized hardware. In this tutorial, we covered how to run your GitHub workflows using Civo.

Looking for more ways to use GitHub actions? Here are some ideas: