Self-Hosted GitHub Actions Runner (macOS) ​
This guide walks through setting up a dedicated Mac as a self-hosted GitHub Actions runner for the installer-app repository.
Prerequisites ​
- macOS machine (Apple Silicon or Intel)
- Admin access to the
zuno-tech/installer-appGitHub repository - GitHub CLI installed and authenticated (
brew install gh && gh auth login)
1. Create the runner directory ​
mkdir -p ~/actions-runner && cd ~/actions-runner2. Download the runner ​
For Apple Silicon (M1/M2/M3/M4):
curl -o actions-runner-osx-arm64.tar.gz -L \
https://github.com/actions/runner/releases/latest/download/actions-runner-osx-arm64-2.321.0.tar.gz
tar xzf actions-runner-osx-arm64.tar.gzFor Intel Macs, replace arm64 with x64 in the URL.
Check for latest version
Visit github.com/actions/runner/releases and update the version number in the URL if a newer release is available.
3. Get a registration token ​
gh api repos/zuno-tech/installer-app/actions/runners/registration-token \
-X POST --jq '.token'This token expires after 1 hour. If it expires before you finish setup, run the command again.
Alternative
You can also get the token from the GitHub UI: Repository Settings > Actions > Runners > New self-hosted runner. The token is shown in the ./config.sh command on that page.
4. Configure the runner ​
cd ~/actions-runner
./config.sh \
--url https://github.com/zuno-tech/installer-app \
--token YOUR_TOKEN_HERE \
--name "runner-name" \
--labels self-hosted,macOS,ARM64 \
--unattendedReplace YOUR_TOKEN_HERE with the token from step 3, and runner-name with a descriptive name for the machine.
5. Start the runner ​
Option A: Run interactively (for testing) ​
cd ~/actions-runner
./run.shThe runner will stay active as long as the terminal is open. Press Ctrl+C to stop.
Option B: Install as a service (for a dedicated machine) ​
cd ~/actions-runner
sudo ./svc.sh install
sudo ./svc.sh startThis installs a launchd service that starts the runner on boot and keeps it running.
Useful service commands:
sudo ./svc.sh status # Check if running
sudo ./svc.sh stop # Stop the service
sudo ./svc.sh start # Start the service
sudo ./svc.sh uninstall # Remove the service6. Verify ​
Confirm the runner appears as Online at:
github.com/zuno-tech/installer-app/settings/actions/runners
Using the runner in workflows ​
Target the self-hosted runner in a workflow with runs-on: self-hosted:
jobs:
example:
runs-on: self-hosted
steps:
- run: echo "Running on self-hosted runner"You can also target specific labels:
runs-on: [self-hosted, macOS, ARM64]Removing a runner ​
To deregister the runner from the repository:
cd ~/actions-runner
./config.sh remove --token YOUR_TOKEN_HEREOr remove it from the GitHub UI under Settings > Actions > Runners.
Security Considerations ​
Private repositories only
Never use self-hosted runners on public repositories. Anyone who can open a PR could execute arbitrary code on your machine.
- Use a dedicated machine. Don't run self-hosted runners on developer laptops or machines with access to production systems.
- Limit network access. Place the runner on a network segment that can't reach sensitive internal services.
- Don't store secrets on disk. Use GitHub Actions secrets or a secrets manager like Doppler.
- Rotate the runner periodically. Remove and re-register runners to refresh credentials.
- Monitor for anomalies. Check runner logs in
~/actions-runner/_diag/and set up alerts for unexpected offline status.
For comprehensive security guidance, see GitHub's self-hosted runner security docs.
Troubleshooting ​
"A session for this runner already exists" ​
Another process is already connected for this runner. Kill existing processes:
pkill -f "Runner.Listener"Then start the runner again.
Runner shows as Offline ​
- Check the runner process is running:
ps aux | grep Runner.Listener - If using the service:
sudo ./svc.sh status - Ensure the machine has internet access to reach GitHub
Token expired during setup ​
Registration tokens expire after 1 hour. Generate a new one with the gh api command from step 3.