Skip to content

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-app GitHub repository
  • GitHub CLI installed and authenticated (brew install gh && gh auth login)

1. Create the runner directory ​

bash
mkdir -p ~/actions-runner && cd ~/actions-runner

2. Download the runner ​

For Apple Silicon (M1/M2/M3/M4):

bash
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.gz

For 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 ​

bash
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 ​

bash
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 \
  --unattended

Replace 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) ​

bash
cd ~/actions-runner
./run.sh

The 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) ​

bash
cd ~/actions-runner
sudo ./svc.sh install
sudo ./svc.sh start

This installs a launchd service that starts the runner on boot and keeps it running.

Useful service commands:

bash
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 service

6. 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:

yaml
jobs:
  example:
    runs-on: self-hosted
    steps:
      - run: echo "Running on self-hosted runner"

You can also target specific labels:

yaml
runs-on: [self-hosted, macOS, ARM64]

Removing a runner ​

To deregister the runner from the repository:

bash
cd ~/actions-runner
./config.sh remove --token YOUR_TOKEN_HERE

Or 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:

bash
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.