--- sidebar_position: 1 --- # Install from a binary The runner is a single binary, `gitea-runner`, built for Linux, macOS, Windows, and FreeBSD. ## Download Download releases from [dl.gitea.com/gitea-runner](https://dl.gitea.com/gitea-runner/). Find builds from the `main` branch in its [`nightly`](https://dl.gitea.com/gitea-runner/nightly/) directory. Each binary has a matching `.sha256` checksum file: ```bash VERSION=nightly curl -sSLO "https://dl.gitea.com/gitea-runner/$VERSION/gitea-runner-$VERSION-linux-amd64" curl -sSLO "https://dl.gitea.com/gitea-runner/$VERSION/gitea-runner-$VERSION-linux-amd64.sha256" sha256sum -c "gitea-runner-$VERSION-linux-amd64.sha256" sudo install -m 0755 "gitea-runner-$VERSION-linux-amd64" /usr/local/bin/gitea-runner ``` To build the runner yourself, run `make build` in a clone of [gitea/runner](https://gitea.com/gitea/runner). ## First run ```bash gitea-runner register --instance https://gitea.example.com --token gitea-runner daemon ``` `register` prompts for the remaining settings and writes the `.runner` registration file to the working directory. Run `daemon` from the same directory so it can read the file. See [Registration](../registration.md). ## systemd Create a user and a configuration file. Then register the runner as that user from its home directory: ```bash sudo useradd --system --home-dir /var/lib/gitea-runner --create-home gitea-runner sudo mkdir -p /etc/gitea-runner sudo gitea-runner config init -c /etc/gitea-runner/config.yaml sudo chown gitea-runner /etc/gitea-runner/config.yaml cd /var/lib/gitea-runner sudo -u gitea-runner gitea-runner register -c /etc/gitea-runner/config.yaml \ --instance https://gitea.example.com --token ``` Install the unit as `/etc/systemd/system/gitea-runner.service`: ```ini [Unit] Description=Gitea Actions runner Documentation=https://gitea.com/gitea/runner After=network-online.target Wants=network-online.target # Uncomment when jobs use the local Docker daemon: # After=docker.service # Requires=docker.service [Service] Type=simple ExecStart=/usr/local/bin/gitea-runner daemon --config /etc/gitea-runner/config.yaml WorkingDirectory=/var/lib/gitea-runner User=gitea-runner Group=gitea-runner Restart=on-failure RestartSec=5s TimeoutStopSec=3h [Install] WantedBy=multi-user.target ``` ```bash sudo systemctl daemon-reload sudo systemctl enable --now gitea-runner ``` Stopping the service cancels running jobs unless `runner.shutdown_timeout` gives them time to finish. Keep `runner.shutdown_timeout` below `TimeoutStopSec`: ```bash sudo -u gitea-runner gitea-runner config set -c /etc/gitea-runner/config.yaml runner.shutdown_timeout 2h50m ``` For jobs in containers, give the `gitea-runner` user access to the Docker daemon's socket, for example through the `docker` group. That access is [equivalent to root](https://docs.docker.com/engine/security/#docker-daemon-attack-surface) on the host. Set the runner's environment variables, such as [proxy settings](../proxy.md), with `Environment=` lines in the unit. ## launchd (macOS) On macOS, run the runner in the login session of the user that jobs should run as. Jobs then have that user's login keychain and the GUI. Register the runner as that user, with a [host label](../labels.md) so that jobs run on the Mac itself: ```bash mkdir ~/gitea-runner && cd ~/gitea-runner gitea-runner register --instance https://gitea.example.com --token --labels macos-latest:host ``` Replace `/Users/gitea-runner` with the user's home directory, then save this file as `~/Library/LaunchAgents/com.gitea.runner.plist`: ```xml Label com.gitea.runner ProgramArguments /usr/local/bin/gitea-runner daemon WorkingDirectory /Users/gitea-runner/gitea-runner EnvironmentVariables PATH /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin StandardErrorPath /Users/gitea-runner/gitea-runner/runner.log RunAtLoad KeepAlive ``` Start the runner. From now on, it also starts whenever the user logs in: ```bash launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.gitea.runner.plist ``` Enable automatic login for the user in System Settings, so that the runner starts after a restart too. macOS does not offer automatic login while FileVault is on. The runner does not get the environment of your shell. Set what jobs need, such as [proxy settings](../proxy.md), in `EnvironmentVariables`. ### Local network access macOS blocks a runner that was started this way from other hosts on the Mac's own subnet, such as the Gitea instance or a shared cache server. The runner then logs `no route to host`. Commands run in Terminal or over SSH are not blocked, so registering works even when the running runner cannot connect. See [local network privacy](https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy). macOS asks on the Mac's screen whether to allow the access. To allow it without that prompt, exempt the subnet on macOS 15.5 or later and restart the Mac. On Wi-Fi, the key is `AllowedWiFiLocalNetworkAddresses`: ```bash sudo defaults write com.apple.network.local-network AllowedEthernetLocalNetworkAddresses -array "192.168.1.0/24" ``` ### Git credentials Git on macOS saves credentials from remote URLs to the keychain, which can stop a job at a dialog that nobody answers. To turn that off, set `GIT_CONFIG_NOSYSTEM` to `1` in `EnvironmentVariables`. ## Windows Run `gitea-runner daemon` with a service wrapper such as [WinSW](https://github.com/winsw/winsw). The runner has no service installer of its own. On macOS and Windows, jobs usually run directly on the runner's machine with [host labels](../labels.md).