Skip to content

Self-Hosted Runners

All CI/CD runs on self-hosted GitHub Actions runners on a Mac Mini M1.

Topology

flowchart TB
    subgraph mac["Mac Mini M1 (macOS)"]
        direction TB
        r1["mac-mini-m1<br/>~/actions-runner<br/>(nutri-e)"]
        r2["mac-mini-star-rewards<br/>~/actions-runner-star-rewards"]
        r3["mac-mini-cutie<br/>~/actions-runner-cutie"]
        r4["mac-mini-ios-sdk<br/>~/actions-runner-ios-sdk"]
        r5["mac-mini-ios-link-sdk<br/>~/actions-runner-ios-link-sdk"]
    end

    subgraph colima["Colima VM (Ubuntu/Docker)"]
        direction TB
        u1["ubuntu-cutie-1<br/>2 CPU, 6GB"]
        u2["ubuntu-cutie-2<br/>2 CPU, 6GB"]
        u3["ubuntu-nutrie-{1..3}<br/>2 CPU, 4GB each"]
        u4["ubuntu-star-rewards-{1..3}<br/>2 CPU, 4GB each"]
    end

    gh["GitHub Actions"]
    gh -->|"self-hosted, macOS, ios"| mac
    gh -->|"self-hosted, Linux"| colima

macOS Runners (iOS Builds)

Each repo has a dedicated macOS runner:

Runner Location Registered To Labels
mac-mini-m1 ~/actions-runner nutri-e self-hosted, macOS, ARM64, ios
mac-mini-star-rewards ~/actions-runner-star-rewards star-rewards self-hosted, macOS, ARM64, ios
mac-mini-cutie ~/actions-runner-cutie cutie self-hosted, macOS, ARM64, ios
mac-mini-ios-sdk ~/actions-runner-ios-sdk ios-sdk self-hosted, macOS, ARM64, ios
mac-mini-ios-link-sdk ~/actions-runner-ios-link-sdk ios-link-sdk self-hosted, macOS, ARM64, ios

Management

# Check all runner services
launchctl list | grep -i actions.runner

# Check specific runner status
cd ~/actions-runner && ./svc.sh status
cd ~/actions-runner-star-rewards && ./svc.sh status

Ubuntu Runners (Docker/Colima)

Linux runners run inside Docker containers via Colima with Rosetta x86 emulation.

Property Value
Container runtime Colima with Rosetta
Cutie runners 2 (ubuntu-cutie-{1,2}) -- 2 CPU, 6GB each
Other runners 3 per repo -- 2 CPU, 4GB each
Total runners 8
Labels self-hosted, Linux, ARM64, docker
Auto-start brew services (Colima) + LaunchAgent

Management

# Check status (from workspace root)
cd ubuntu-runner && docker compose ps

# View logs
docker compose logs -f

# Restart
docker compose down && docker compose up -d

# After reboot
colima start --vm-type vz --vz-rosetta && docker compose up -d

ARM64 Limitations

  • Android builds: AAPT2 is x86-only. Use [self-hosted, macOS, ios] for Android.
  • Docker actions: Some x86-only images may fail under Rosetta.

Workflow Configuration

jobs:
  build:
    runs-on: [self-hosted, macOS, ios]
# MUST use macOS -- AAPT2 is x86-only on Linux
jobs:
  build:
    runs-on: [self-hosted, macOS, ios]
    steps:
      - uses: android-actions/setup-android@v3
jobs:
  lint:
    runs-on: [self-hosted, Linux]
jobs:
  scan:
    runs-on: [self-hosted, Linux, docker]

Never use ubuntu-latest alone

It falls back to paid GitHub-hosted runners when self-hosted runners are busy.

Maintenance

A weekly cron job cleans Docker disk space (Sundays 3am). See ubuntu-runner/README.md for details.