Create MacOS gitlab-runner
Installing GitLab Runner on macOS via Homebrew
This guide details a method for installing and configuring a GitLab Runner on macOS to run as a dedicated user service.
1. Install GitLab Runner
First, install the GitLab Runner package using Homebrew:
brew install gitlab-runner
2. Note on Homebrew Paths (Apple Silicon vs. Intel)
Homebrew uses different installation paths depending on your Mac's architecture. You must use the correct path in the following configuration files.
- Apple Silicon (M1/M2/M3): The path is `/opt/homebrew/`.
- Intel: The path is `/usr/local/`.
The examples in this guide use the Apple Silicon path. Remember to change `/opt/homebrew/` to `/usr/local/` if you are on an Intel-based Mac.
3. Switch to the Runner User
For security and isolation, it's best to run the GitLab Runner under a dedicated user account (e.g., `runner`).
su runner
4. Create a Custom `launchd` Service File
This process uses `launchd`, the standard service manager on macOS. For more general information, see the [Services (launchd)] page.
Create a custom `.plist` file in the user's `LaunchAgents` directory to manage the runner process.
nano ~/Library/LaunchAgents/homebrew.mxcl.gitlab-runner-custom.plist
Paste the following XML configuration. Important: If you are on an Intel Mac, change the `ProgramArguments` string from `/opt/homebrew/` to `/usr/local/`.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>homebrew.mxcl.gitlab-runner</string>
<key>LegacyTimers</key>
<true/>
<key>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
<string>Background</string>
<string>LoginWindow</string>
<string>StandardIO</string>
<string>System</string>
</array>
<key>ProcessType</key>
<string>Interactive</string>
<key>ProgramArguments</key>
<array>
<!-- This path is for Apple Silicon. Change to /usr/local/ for Intel. -->
<string>/opt/homebrew/opt/gitlab-runner/bin/gitlab-runner</string>
<string>run</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>/Users/runner</string>
<key>StandardErrorPath</key>
<string>/Users/runner/gitlab-runner.err.log</string>
<key>StandardOutPath</key>
<string>/Users/runner/gitlab-runner.out.log</string>
</dict>
</plist>
5. Configure the GitLab Runner
Next, configure the runner's behavior by editing its `config.toml` file.
nano ~/.gitlab-runner/config.toml
Add the following configuration. Note: GitLab Runner does not support Zsh as a shell for its jobs, so you must explicitly set it to `bash`.
concurrent = 3
check_interval = 30
[session_server]
session_timeout = 1800
[[runners]]
name = "Mac-mini-runner"
limit = 1
url = "https://gitlab.com/"
token = "masked"
executor = "shell"
shell="bash"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
6. Set Up the Shell Environment
To ensure the shell executor has the correct environment variables, configure the `.bashrc` and `.bash_profile` files for the `runner` user.
Create and configure `.bashrc`
nano ~/.bashrc
Add your required environment setup. The `brew shellenv` command and the `PATH` variable are especially important to get right for your architecture.
### Brew ###
# Use the correct path for your architecture.
# Apple Silicon
eval $(/opt/homebrew/bin/brew shellenv)
# Intel
# eval $(/usr/local/bin/brew shellenv)
### Ruby ###
eval "$(rbenv init -)"
### Extra environments ###
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
# Android
export ANDROID_HOME="/Users/runner/Library/Android/sdk"
# Java
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
# Path (ensure /opt/homebrew/bin or /usr/local/bin is included)
export PATH=/Users/runner/.rbenv/shims:/Users/runner/Downloads/flutter/bin:/opt/homebrew/bin:/opt/homebrew/opt/ruby/bin:/opt/homebrew/lib/ruby/gems/3.2.0/bin:/Users/runner/.rbenv/shims:/opt/homebrew/bin:/opt/homebrew/sbin:/Library/flutter/bin:/Library/flutter/.pub-cache/bin:/Users/runner/.pub-cache/bin:/Users/runner/Library/Android/sdk/bundle-tool/:/Users/runner/Library/Android/sdk/platform-tools/:/Users/runner/Library/Android/sdk/cmdline-tools/latest/bin/:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin
# FASTLANE
export FASTLANE_SESSION=masked
export FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD="masked"
export FASTLANE_USER="mobil@example.com"
export FASTLANE_PASSWORD="masked"
export SPACESHIP_ONLY_ALLOW_INTERACTIVE_2FA=true
export SUPPLY_UPLOAD_MAX_RETRIES=5
Create `.bash_profile` to source `.bashrc`
This ensures your `.bashrc` configuration is loaded for new shell sessions.
nano ~/.bash_profile
Add the following lines:
#####
# USE "~/.bashrc" for configuration!
#####
### Import .bashrc ###
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
7. Start and Manage the Runner Service
Finally, use `launchctl` to load your custom service file, which will start the GitLab Runner.
To enable and run the service:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.gitlab-runner-custom.plist
To disable and stop the service:
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.gitlab-runner-custom.plist