Install from a binary
The runner is a single static binary called gitea-runner. It has no dependencies apart from a Docker daemon for containerized jobs.
Download
Section titled “Download”- released builds: dl.gitea.com/gitea-runner or the release page
- development builds of the
mainbranch: dl.gitea.com/gitea-runner/nightly
Each file is published next to a .sha256 checksum and an .xz compressed variant:
VERSION=3.0.2 # any 3.x release, see the release pagecurl -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"install -m 0755 "gitea-runner-$VERSION-linux-amd64" /usr/local/bin/gitea-runnerCheck that the binary matches your platform:
gitea-runner --versionBuild from source
Section titled “Build from source”Building requires the Go version declared in the repository’s go.mod:
git clone https://gitea.com/gitea/runner.gitcd runnermake buildFirst run
Section titled “First run”gitea-runner generate-config > config.yaml # optional, defaults are safegitea-runner -c config.yaml register # see "Registering a runner"gitea-runner -c config.yaml daemonThe daemon command runs in the foreground. It reads the registration file (runner.file, .runner by default) relative to its working directory, so keep the working directory stable across restarts.
Run as a systemd service
Section titled “Run as a systemd service”Create an unprivileged user, install the binary, and register the runner as that user so the .runner file ends up in the service’s working directory:
sudo useradd --system --home-dir /var/lib/gitea-runner --create-home gitea-runnersudo install -d /etc/gitea-runnersudo -u gitea-runner gitea-runner generate-config | sudo tee /etc/gitea-runner/config.yaml >/dev/nullcd /var/lib/gitea-runnersudo -u gitea-runner gitea-runner register -c /etc/gitea-runner/config.yamlThen install the unit as /etc/systemd/system/gitea-runner.service:
[Unit]Description=Gitea Actions runnerDocumentation=https://gitea.com/gitea/runnerAfter=network-online.targetWants=network-online.target# Uncomment when jobs use the local Docker daemon:# After=docker.service# Requires=docker.service
[Service]Type=simpleExecStart=/usr/local/bin/gitea-runner daemon --config /etc/gitea-runner/config.yamlWorkingDirectory=/var/lib/gitea-runnerUser=gitea-runnerGroup=gitea-runnerRestart=on-failureRestartSec=5s# Allow running jobs to finish before the runner is stopped. Keep this in sync# with runner.shutdown_timeout in the config.TimeoutStopSec=3h
[Install]WantedBy=multi-user.targetsudo systemctl daemon-reloadsudo systemctl enable --now gitea-runnerIf jobs use the host’s Docker daemon, the gitea-runner user also needs access to the daemon socket. Adding it to the docker group grants that access and is equivalent to root on the host.
Environment variables for the process — most importantly proxy variables — belong in Environment= lines or a drop-in file, not in the runner config.
Run as a launchd daemon (macOS)
Section titled “Run as a launchd daemon (macOS)”macOS uses launchd instead of systemd. Daemons run as root by default; an unprivileged _gitea-runner user can be created with dscl. Install the following as /Library/LaunchDaemons/com.gitea.runner.plist and adjust the paths to your installation:
<?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>Label</key> <string>com.gitea.runner</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/gitea-runner</string> <string>daemon</string> <string>--config</string> <string>/etc/gitea-runner/config.yaml</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>WorkingDirectory</key> <string>/var/lib/gitea-runner</string> <key>StandardOutPath</key> <string>/var/lib/gitea-runner/runner.log</string> <key>StandardErrorPath</key> <string>/var/lib/gitea-runner/runner.err</string> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string> <key>HOME</key> <string>/var/lib/gitea-runner</string> </dict> <key>UserName</key> <string>_gitea-runner</string></dict></plist>sudo launchctl load /Library/LaunchDaemons/com.gitea.runner.plistOn macOS and Windows hosts, jobs usually run with host labels and the tools installed on the machine.
Windows
Section titled “Windows”Install the windows-amd64 binary and register it as a service with any service wrapper (for example sc.exe plus a wrapper such as WinSW, or a scheduled task at boot). The runner itself has no service-installer subcommand.
Keep in mind for Windows hosts:
runner.post_task_scriptaccepts.exe,.batand.cmdpaths;.ps1is not supported as the configured path.- host-mode jobs are terminated as a process tree, so tools that daemonize are not left behind.