DevOps: Self-Hosted GitHub Actions Runner with Docker on Pi 5¶
Automating software compilation, testing, and deployment (CI/CD) is essential for modern development. While GitHub provides free cloud hosting minutes for shared runners, these runners are limited to x86_64 architecture and can be slow for compiling ARM64 binaries (which requires QEMU emulation).
By setting up a self-hosted GitHub Actions runner on a Raspberry Pi 5, you get: 1. Native ARM64 Compilation: Drastically accelerates compilation speeds for Docker images and binary releases targetting Raspberry Pi or edge devices. 2. Access to Local Hardware: Workflows can deploy directly to local homelab storage, Docker networks, or interact with physical GPIO pins. 3. Unlimited Build Minutes: Run high-frequency, complex pipelines entirely free of charge.
This guide walks you through running an isolated, containerized GitHub Actions runner on Raspberry Pi 5.
Architecture Overview¶
Step 1: Generate the Runner Token in GitHub¶
First, generate the necessary authorization token from your target GitHub repository:
- Navigate to your GitHub repository (or organization).
- Go to Settings -> Actions -> Runners in the left sidebar.
- Click New self-hosted runner.
- Select Linux as the runner image, and ARM64 as the architecture.
- In the shown configuration instructions, copy the registration token and repository URL.
(The token looks like:
AN735B0x...).
Step 2: Build the Containerized Runner (Dockerfile)¶
For security and reproducibility, we will run the runner inside an isolated Docker container rather than directly on the host OS.
Create a workspace directory:
Create a Dockerfile defining the runner environment, including basic tools (git, curl, docker-cli):
Add the following Dockerfile configuration:
Step 3: Create the Entrypoint Registration Script¶
The entrypoint script registers the runner with GitHub using the token on container boot, and gracefully de-registers it when the container stops.
Create the file:
Add the script:
Step 4: Write the Docker Compose Configuration¶
This compose configuration links the runner to the host's Docker daemon (/var/run/docker.sock), allowing the runner to spin up Docker-in-Docker workflows (e.g. docker build) directly.
Create the file:
Add the configuration (replace <YOUR_REPO_URL> and <YOUR_REGISTRATION_TOKEN>):
Build the image and launch the container:
Verify that the runner is successfully connected to GitHub:
Step 5: Test the Runner with a Workflow¶
Let's test if our Raspberry Pi 5 runs native ARM64 jobs correctly.
In your GitHub repository, create a workflow file: .github/workflows/test-pi.yml:
Push the commit to GitHub. In the Actions tab of your repository, select the triggered workflow. You will see that the job instantly schedules onto your local Raspberry Pi 5 container, executing the steps natively and showing aarch64 in the logs!
Security Best Practices¶
[!WARNING] Never run self-hosted runners on Public repositories. Anyone can fork a public repository, submit a Pull Request with a modified workflow file (e.g., executing malicious bash commands), and trigger it to run on your local Raspberry Pi, compromising your home network. Use self-hosted runners only for Private repositories.
By integrating this containerized GitHub Actions runner, your Raspberry Pi 5 becomes an efficient, ARM64-native automation server, supercharging your local software deployment pipelines.