ci+cd,  github actions,  docker

Dockerized Multi-arch Github Actions Runner

Dockerized Multi-arch Github Actions Runner

Do you want to run the Github Action runner as a container? Do you want to run it on your Docker or Kubernetes cluster and scale the number of runners easily? This is your post :)

We are going to the point here, just a few explanations. If you want to know further, you have a few links at the bottom.

Dockerfile

#syntax=docker/dockerfile:1.3-labs
FROM ubuntu:20.04
ARG TARGETARCH

ENV RUNNER_VERSION=${RUNNER_VERSION:-2.291.1}

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

WORKDIR /actions-runner
RUN <<EOT 
    export ARCH=${TARGETARCH}
    # When the arch is amd64, the Github runner binary to use is x64.
    if [ "amd64" = "$TARGETARCH" ]; then
        export ARCH="x64"
    fi

    curl -o /actions-runner/actions-runner-linux.tar.gz -L \
        https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz 
EOT

RUN tar xzf ./actions-runner-linux.tar.gz
RUN rm ./actions-runner-linux.tar.gz

COPY entrypoint.sh .
RUN chmod -R 7700 entrypoint.sh

RUN adduser --no-create-home github -uid 1001
RUN chown -R github:github /actions-runner

USER github

ENTRYPOINT ["/actions-runner/entrypoint.sh"]

The keys are the ARG TARGETARCH that the docker build command will provide and the checks when the architecture is amd64.

docker-compose.yml

version: '3.5'

services:
  github-action-runner:
    build: 
      context: .
      dockerfile: Dockerfile 
    image: ${DOCKER_REPOSITORY:-nexus.playtomic.io}/playtomic-github-action-runner:${VERSION:-latest}
    environment:
      - GH_ORGANIZATION=syltek
      - GH_ACCESS_TOKEN=${GH_ACCESS_TOKEN}
    logging:
      options:
        max-size: 10M
    deploy:
      placement:
        constraints: [node.role == worker]
      replicas: ${REPLICAS:-1}
      update_config:
        parallelism: 1
        failure_action: rollback

entrypoint.sh

#!/bin/bash
set -e

cleanup() {
  GH_RUNNER_TOKEN=$1
  echo "Removing runner with token ${GH_RUNNER_TOKEN}..."
  ./config.sh remove --token ${GH_RUNNER_TOKEN}
}

# GH_ACCESS_TOKEN must be a token with admin:org permissions https://github.com/settings/tokens/
if [ -z ${GH_ACCESS_TOKEN+x} ]; then
  echo "GH_ACCESS_TOKEN environment variable is not set"
  exit 1
fi

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

# Generate a runner token from our Github Access Token. Every runner needs a new token.
GH_RUNNER_TOKEN=$(curl -sX POST -H "Authorization: token ${GH_ACCESS_TOKEN}" https://api.github.com/orgs/${GH_ORGANIZATION}/actions/runners/registration-token | jq .token --raw-output)
echo "Using the following token to register the runner: ${GH_RUNNER_TOKEN}"

# Traps are here to unregister the runners on docker stop, but they are not being triggered.
#trap 'cleanup ${GH_RUNNER_TOKEN}; exit 143' SIGTERM
#trap 'cleanup ${GH_RUNNER_TOKEN}; exit 2' SIGINT

cleanup ${GH_RUNNER_TOKEN}
/actions-runner/config.sh --runnergroup Cluster --url https://github.com/$GH_ORGANIZATION --token $GH_RUNNER_TOKEN --replace
/actions-runner/run.sh
docker buildx build --platform linux/amd64 .
docker buildx build --platform linux/arm64 .
GH_ACCESS_TOKEN=your-token docker-compose up

Inspiration: