Skip to content

Instantly share code, notes, and snippets.

@some-natalie
Last active September 11, 2025 20:02
Show Gist options
  • Select an option

  • Save some-natalie/1c7cb6cb56ee6f16ab7e3b535fb8cc6a to your computer and use it in GitHub Desktop.

Select an option

Save some-natalie/1c7cb6cb56ee6f16ab7e3b535fb8cc6a to your computer and use it in GitHub Desktop.
chainguard-base github actions-runner-controller image
FROM cgr.dev/chainguard-private/dotnet-sdk:8-dev AS build
# Arguments
ARG TARGETPLATFORM
ARG RUNNER_VERSION=2.328.0
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.7.0
ARG DOTNET_VERSION=8
ARG NODE_VERSION=24
# Become root
USER root
# Set up the non-root user (runner)
RUN addgroup -S runner && adduser -S runner -G runner
# Install software
RUN apk add --no-cache \
aspnet-${DOTNET_VERSION}-runtime \
bash \
build-base \
ca-certificates \
curl \
docker-cli \
dumb-init \
git \
gh \
helm \
icu \
jq \
krb5-libs \
lttng-ust \
nodejs-${NODE_VERSION} \
openssl \
openssl-dev \
wget \
unzip \
yaml-dev \
zlib
RUN export PATH=$HOME/.local/bin:$PATH
# Shell setup
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Make and set the working directory
RUN mkdir -p /home/runner \
&& chown -R runner:runner /home/runner
WORKDIR /home/runner
RUN test -n "$TARGETPLATFORM" || (echo "TARGETPLATFORM must be set" && false)
# Runner download supports amd64 and x64
RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
&& if [ "$ARCH" = "amd64" ]; then export ARCH=x64 ; fi \
&& curl -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \
&& tar xzf ./runner.tar.gz \
&& rm runner.tar.gz
# remove bundled nodejs and symlink to system nodejs
RUN rm /home/runner/externals/node24/bin/node && ln -s /usr/bin/node /home/runner/externals/node24/bin/node
# optionally, if you want to force node20 to be node24 as well
RUN rm /home/runner/externals/node20/bin/node && ln -s /usr/bin/node /home/runner/externals/node20/bin/node
# Install container hooks
RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \
&& unzip ./runner-container-hooks.zip -d ./k8s \
&& rm runner-container-hooks.zip
# configure directory permissions; ref https://github.com/actions/runner-images/blob/main/images/ubuntu/scripts/build/configure-system.sh
RUN chmod -R 777 /opt /usr/share
# squash it!
FROM scratch AS final
LABEL org.opencontainers.image.source="https://github.com/some-natalie/kubernoodles"
LABEL org.opencontainers.image.path="images/chainguard-base.Dockerfile"
LABEL org.opencontainers.image.title="chainguard-base"
LABEL org.opencontainers.image.description="A Chainguard runner image for GitHub Actions"
LABEL org.opencontainers.image.authors="Natalie Somersall (@some-natalie)"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.documentation="https://github.com/some-natalie/kubernoodles/README.md"
ENV RUNNER_MANUALLY_TRAP_SIG=1
ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
USER runner
COPY --from=build / /
## githubConfigUrl is the GitHub url for where you want to configure runners
## ex: https://github.com/myorg/myrepo or https://github.com/myorg
# These runners test and attach themselves to this repo
# ** change this to what you really want **
githubConfigUrl: "repo/org/enterprise"
## githubConfigSecret is the k8s secrets to use when auth with GitHub API.
## You can choose to use GitHub App or a PAT token
githubConfigSecret:
## GitHub Apps Configuration
# NOTE: IDs MUST be strings, use quotes
github_app_id: "number"
github_app_installation_id: "number"
github_app_private_key: |
-----BEGIN RSA PRIVATE KEY-----
key goes here
-----END RSA PRIVATE KEY-----
### GitHub PAT Configuration
# github_token: ""
## maxRunners is the max number of runners the auto scaling runner set will scale up to.
maxRunners: 5
## minRunners is the min number of runners the auto scaling runner set will scale down to.
minRunners: 1
# runnerGroup: "default"
template:
spec:
initContainers:
- name: init-dind-externals
image: chainguard-base:test
imagePullPolicy: IfNotPresent
command:
["cp", "-r", "-v", "/home/runner/externals/.", "/home/runner/tmpDir/"]
volumeMounts:
- name: dind-externals
mountPath: /home/runner/tmpDir
containers:
- name: runner
image: chainguard-base:test
imagePullPolicy: IfNotPresent
command: ["/home/runner/run.sh"]
env:
- name: DOCKER_HOST
value: tcp://localhost:2376
- name: DOCKER_TLS_VERIFY
value: "1"
- name: DOCKER_CERT_PATH
value: /certs/client
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-cert
mountPath: /certs/client
readOnly: true
- name: dind
image: cgr.dev/chainguard-private/docker-dind:latest
imagePullPolicy: IfNotPresent
securityContext:
privileged: true
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-cert
mountPath: /certs/client
- name: dind-externals
mountPath: /home/runner/externals
volumes:
- name: work
emptyDir: {}
- name: dind-cert
emptyDir: {}
- name: dind-externals
emptyDir: {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment