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: