DEV Community

loading...
Cover image for Deploying GitHub Actions Self-Hosted runners on Koyeb
Koyeb

Deploying GitHub Actions Self-Hosted runners on Koyeb

Edouard Bonlieu
CPO at @gokoyeb, formerly VP Product & Marketing at @scaleway.
Originally published at koyeb.com ・6 min read

GitHub Actions allows you to automate your software development workflow lifecycle right in your GitHub repository.
The workflows you deployed let you compose a multitude of jobs including CI/CD.

A GitHub Actions workflow is made of a YAML file containing all the configuration and commands to execute on specific events. The workflow execution is made on runners.
A runner is the application that runs a job from a GitHub Actions workflow. While GitHub natively provides managed runners, it can be interesting to deploy your own in various cases:

  • Need different CPU, disk, and memory resources than the runners offered by GitHub.
  • Need to execute workflows on specific operating systems not offered by GitHub.
  • Require to execute workflows on specific hardware or processor architectures: GPUs, ARM, etc.
  • Need to interact with resources GitHub runners can't access, i.e. services in a virtual private network, etc.
  • Want to control where the workflow execution is performed

In this guide, we will showcase how to deploy GitHub Actions self-hosted runners on Koyeb and run a basic "Hello World!" GitHub Actions workflow.

Requirements

To successfully follow and complete this guide you need:

  • A Koyeb account to deploy and run the GitHub Actions, self-hosted runner
  • A GitHub account with an existing repository and a GitHub Actions workflow you want to run on a self-hosted runner

Steps

To deploy a self-hosted GitHub Actions runner on Koyeb you need to follow these steps:

  1. Build the GitHub Actions runner Docker Image
  2. Push the Docker Image on the GitHub Container Registry
  3. Configure your GitHub repository to use a self-hosted GitHub runner
  4. Deploy the self-hosted GitHub runner on Koyeb
  5. Run a GitHub Actions workflow using a self-hosted GitHub runner

Build the GitHub Actions runner Docker Image

The first step is to create a Dockerfile to install GitHub Action runner. We will then build the Docker image and push it to the GitHub container registry.
As Koyeb allows you to horizontally scale the number of services, you will be able to deploy as many as you need GitHub runners on Koyeb.

To get started, created a new folder we will create the Dockerfile:

mkdir gh-self-hosted-runner
cd gh-self-hosted-runner
Enter fullscreen mode Exit fullscreen mode

In the directory we created, create a Dockerfile file and paste the content below:

FROM ubuntu:latest

ENV RUNNER_VERSION=2.278.0

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    libicu-dev \
    netcat

WORKDIR /gh-runner

RUN curl -o actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz -L \
            https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz

RUN tar xzf actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz

COPY entrypoint.sh .

RUN adduser --no-create-home ghrunner -uid 1001
RUN chown -R ghrunner:ghrunner /gh-runner

USER ghrunner

EXPOSE 3000
ENTRYPOINT ["/gh-runner/entrypoint.sh"]
Enter fullscreen mode Exit fullscreen mode

You may notice we are installing netcat in the Dockerfile. We realize this operation as the Koyeb platform performs TCP health checks on services you deployed to ensure they are up and running.
We use netcat to expose the port 3000 in our GitHub Actions runner application so Koyeb can ensure it is up and running properly.

In the same directory, create an entrypoint.sh file. This file contains the script our container will execute at boot time:

#!/bin/bash

if [ -z ${GH_RUNNER_TOKEN+x} ]; then
  echo "GH_RUNNER_TOKEN environment variable is not set"
  exit 1
fi

if [ -z ${GH_REPOSITORY+x} ]; then
  echo "GH_REPOSITORY environment variable is not set."
  exit 1
fi

nohup nc -lk 3000 &

/gh-runner/config.sh --url https://github.com/$GH_REPOSITORY --token $GH_RUNNER_TOKEN
/gh-runner/run.sh
Enter fullscreen mode Exit fullscreen mode

Build the Docker image by executing the following command:

docker build . -t ghcr.io/<YOUR_GITHUB_USERNAME>/gh-self-hosted-runner
Enter fullscreen mode Exit fullscreen mode

Take care to replace <YOUR_GITHUB_USERNAME> with your GitHub username

Push the Docker Image on the GitHub Container Registry

With our Docker image is built, we can now upload it to the GitHub container registry. In your terminal run the command below to push the image.

docker push ghcr.io/<YOUR_GITHUB_USERNAME>/gh-self-hosted-runner
Enter fullscreen mode Exit fullscreen mode

Within a few minutes, you will see your Docker image available on the GitHub container registry: https://github.com/<YOUR_GITHUB_USERNAME>?tab=packages.

Configure your GitHub repository to use a self-hosted GitHub Actions runner

On GitHub, go to the repository you want to use the self-hosted GitHub Actions runner and click the Settings tab. On the left-side menu, click Actions and select runners in the submenu.

You land on the runners settings page. Click the Add runner button to add a new self-hosted runner, the runner configuration page appears.

In the Configure section, copy the token, i.e. here: AATHLD2AEXMPRBIPVTZVHMTAVTEOR, and save it a safe place. You will need it in the next section when deploying the GitHub Actions runner on Koyeb.

./config.sh --url https://github.com/edouardb/runner-test --token AATHLD2AEXMPRBIPVTZVHMTAVTEOR
Enter fullscreen mode Exit fullscreen mode

Deploy the self-hosted GitHub runner on Koyeb

To deploy the self-hosted GitHub runner on Koyeb, go to the Koyeb Control Panel and click the Create App button.

In the form, fill the Docker image field with the name of the image we previously created which should look like ghcr.io/<YOUR_GITHUB_USERNAME>/gh-self-hosted-runner.

Check the box Use a private registry and, in the select field, click Create Registry Secret.

A modal opens asking for:

  • a name for the Secret which will be created, for instance gh-registry-secret
  • the registry provider to generate the secret containing your private registry credentials, in our case GitHub
  • your GitHub username and a valid GitHub token having registry read/write permissions as password Once you've filled all the fields, click the Create button.

In the Ports section, change the export port from 80 to 3000 and from protocol HTTP to TCP. This setting is required to let Koyeb performs health checks and ensure your service is up and running properly.

In the Environment variables section created two environment variables:

  • GH_REPOSITORY: having for value the name of your GitHub repository, i.e. org-name/repo-name
  • GH_RUNNER_TOKEN: having for value the GitHub runner token you created in the previous section. We strongly recommend to use an environment variable of type Secret to store it.

Give your App a name, i.e gh-self-hosted-runner, and click Create App

You can add more regions to deploy your applications, and define the horizontal scaling according to your needs.

Yours GitHub Actions self-hosted runner app is now deployed and running. In the next section, we will deploy a Hello World! GitHub Actions workflow executing on our self-hosted runner.

Run a GitHub Actions workflow using a self-hosted GitHub runner

Execute a new GitHub Actions workflow on a self-hosted GitHub runner

If you do not have any GitHub Actions workflow, in your git repository create a new folder to store our GitHub Actions workflow:

mkdir -p github/workflows
cd github/workflows
Enter fullscreen mode Exit fullscreen mode

Create a new file to store our example workflow called main.yaml and paste the content below:

name: CI
on: [push]

jobs:
  build:
    runs-on: self-hosted
    steps:
    - run: echo "Hello from Koyeb runner!"
Enter fullscreen mode Exit fullscreen mode

The workflow above execute on the runner hosted on Koyeb and display "Hello from Koyeb runner!" each time a push occurs on your repository.

To test it, commit and push changes to your repository, in the Actions tabs of your repository on GitHub, you will see the result of the workflow executed by your GitHub runner running on Koyeb.

Execute an existing GitHub Actions workflow on a self-hosted GitHub runner

In your workflow YAML file, edit the runs-on section of your workflow and set its value to self-hosted to run a self-hosted GitHub runner:

name: CI
on: [push]

jobs:
  build:
    runs-on: self-hosted
    ...
Enter fullscreen mode Exit fullscreen mode

In this guide, we demonstrated the benefit of using GitHub actions self-hosted runners and how to deploy them on Koyeb. If you have any questions or suggestions to improve this guide,
feel free to reach us out on Slack.

Discussion (0)