Files
docs/runner-docs_versioned_docs/version-5/upgrade.md
T
bircni a874918bb7 Document runner 4 and 5, regenerate the 28.2.0 api documents (#599)
The 28.2.0 bump in #594 only changed the version string of the api documents, so they still listed the 28.1.0 endpoints. They are now regenerated from v28.2.0 (mostly new `423 repoArchivedError` responses).

The runner docs stopped at 3.3.0 while the runner is at 5.1.1:

- cut the runner `4` and `5` series, `/runner/` now serves 5.1.1 and `/runner/4/` 4.1.0, the `3` series is bumped to 3.5.0
- series specific image tags and versions in the new copies, the `3` series no longer claims the `latest` tag
- 4.0 and 5.0 sections in the upgrade guide, and the Git 2.34.1 requirement of 5.0 in the requirements
- regenerated every reference page from the newest stable tag of its series

Reviewed-on: https://gitea.com/gitea/docs/pulls/599
Reviewed-by: TheFox0x7 <[email protected]>
2026-10-20 19:19:28 +00:00

8.7 KiB

sidebar_position
sidebar_position
8

Upgrading

A runner upgrade is a binary or image replacement: stop the daemon, swap it, start it again. The registration file stays valid across versions, so a runner keeps its identity and does not have to be registered again.

sudo systemctl stop gitea-runner
sudo install -m 0755 gitea-runner-<version>-linux-amd64 /usr/local/bin/gitea-runner
sudo systemctl start gitea-runner

With runner.shutdown_timeout set, stop lets the jobs in flight finish first; without it, they are cancelled and Gitea reschedules them.

Config files are read leniently: keys the running version does not know are reported as a warning and ignored, so one file can be shared by runners of different versions. Compare your file with gitea-runner generate-config after an upgrade to pick up new options.

5.0

Breaking

  • Git 2.34.1 or newer is required. Actions and reusable workflows are downloaded with Git, so the runner needs git on its PATH. builtin:checkout runs Git inside the job too, so job images need Git, and the job must reach Gitea and trust its certificate. The official runner images include Git.
  • builtin:checkout works like actions/checkout. It removes untracked and ignored files from the checkout directory unless clean: false is set, and fails when the triggering tag was moved after the workflow started. In exchange it gains SSH keys, LFS, submodules, sparse checkout, partial clones, the fetch-tags, clean, show-progress and set-safe-directory inputs, and the ref and commit outputs.
  • Config values expand ${NAME}. A value containing ${NAME} reads that variable from the runner's environment, and the config fails to load when it is unset. Write $${NAME} to keep a literal ${NAME}, for example in a shell command inside a Kubernetes pod_template.
  • Jobs require runs-on. A job without runs-on, or with an empty one, fails instead of running in runner.default_image, like on GitHub. Jobs that call a reusable workflow are exempt.
  • Metrics follow the OpenTelemetry semantic conventions. OTLP metric names, units, types and attributes change, see docs/telemetry.md. On /metrics, gitea_runner_client_errors_total gains a code label, and gitea_runner_job_total counts jobs stopped by runner.timeout as timeout.
  • Unprivileged runners ignore log and OOM options from workflows. Unless container.privileged is set, --log-driver, --log-opt, --oom-score-adj and --oom-kill-disable are dropped from a job's container.options with a warning.

Also new

  • Mutual TLS to Gitea (runner.client_cert_file, runner.client_key_file) and runner.extra_headers for headers a reverse proxy in front of Gitea requires.
  • SHA-256 repositories for actions, reusable workflows and builtin:checkout.
  • :ro entries in container.valid_volumes, which only allow read-only mounts, and container.sweep: false to keep services that jobs deploy to the runner's Docker daemon.
  • The gitea_runner_state metric, reporting whether the runner is busy, idle or unavailable.
  • From 5.1: action pre and post steps shown as their own steps on Gitea versions that support it, startup retried while Gitea is unreachable, and runner.log_report_level to set the level of runner messages in the job log independently of log.level.

4.0

Breaking

  • Jobs reach the cache through their runner. With cache.external_server set, jobs send their cache requests to their runner, which forwards them; only the runner has to reach the external server, and that server no longer has to reach Gitea. Jobs that cannot reach their runner, such as on a remote DOCKER_HOST, need cache.host and cache.port set to an address they can reach.
  • container.network: bridge cuts jobs off from a containerized runner. Jobs on the default bridge network cannot reach a runner container outside it, so their cache and artifact uploads fail. Leave container.network empty or use a user-defined network.
  • * in container.valid_volumes no longer matches across /. A host pattern that relied on * matching nested paths needs **, for example /data/** instead of /data/*.

Also new

  • builtin:checkout, which needs neither a download nor Node in the job image, see docs/builtin-actions.md, and the self: prefix for actions hosted on the runner's own instance.
  • S3-compatible storage as a cache backend (cache.s3 in the example configuration), shared between runners without a cache server.
  • OpenTelemetry tracing of jobs and steps, and from 4.1 the Prometheus metrics exported through OpenTelemetry as well.
  • A Kubernetes backend that runs jobs as pods (4.1), see docs/kubernetes.md.
  • A runner container on the jobs' Docker daemon joins every job network, so jobs reach its cache without cache.host, and --umask is accepted in container.options.

3.0

Breaking

  • Container options from workflows are filtered. While container.privileged is disabled, options in a job's container.options that would escape the container are stripped with a warning: --pid, --ipc, --uts, --cgroupns, --userns, --cap-add, --security-opt, --device, --device-cgroup-rule, --gpus, --volumes-from, --runtime, --cgroup-parent, --sysctl. Workflows that relied on them need a runner with privileged mode enabled.
  • One process per registration file. The daemon takes an advisory lock on <runner.file>.lock and refuses to start when another process already uses that file. Setups that started several runners from one directory must give each its own runner.file (or its own working directory).
  • Cache service v2 is served and enabled by default. actions/[email protected] and later, and the stock actions/upload-artifact / download-artifact from v4.4.0 on, reach it through a patch the runner applies to the action's own bundle. Jobs are pointed at the runner's cache server as their results service, which then forwards artifact calls to Gitea. Set cache.v2: false to keep to v1.

Also new

  • Job hooks (runner.hooks.job_started / job_completed) running inside the job environment.
  • Proxy variables propagated to jobs, service containers and Dockerfile action builds.
  • Secrets are masked in the log even when a job prints them in an encoded form.
  • The tool cache can be relocated, and runner-managed paths can be mounted over, via container.options.

2.0

Breaking

  • DOCKER_USERNAME / DOCKER_PASSWORD are no longer implicit pull credentials. They used to be attached to every image pull, which sent private-registry credentials to Docker Hub for public images. They are ordinary secrets now. Migrate to:
    • container.credentials (and service credentials) in the workflow for private images;
    • a docker login performed on the runner host, or a job hook, for private uses: docker://... actions.
  • container.force_pull now defaults to false in the generated example config, so images already present are reused unless you ask for a pull.
  • No environment variable overrides for the config. GITEA_DEBUG, GITEA_TRACE, GITEA_RUNNER_CAPACITY, GITEA_RUNNER_FILE, GITEA_RUNNER_ENVIRON and GITEA_RUNNER_ENV_FILE are ignored; use a config file. The Docker images' entrypoint variables are unaffected.

Also new

  • Post-task script (runner.post_task_script) for host housekeeping between jobs.
  • Health checks (health_check.*) that pause task admission on low disk space or a failing script.
  • register --token-file, and GITEA_RUNNER_LABELS honoured by daemon, so labels can change without re-registering.
  • jobs.<job_id>.timeout-minutes and jobs.<job_id>.continue-on-error support, job summaries, shallow action clones (runner.action_shallow_clone), ssh:// action URLs, IPv4/IPv6 options for auto-created networks, --platform and --pull in container.options, cache.external_secret_file, a GitHub-style "Set up job" log section, and pre/post entrypoints of Docker actions.

Downgrading

Downgrading a runner is possible — the registration file format has not changed — but a config file written for a newer version may carry keys the older one ignores, and features such as cache service v2 stop being served, so jobs that came to rely on them fail. Test a downgrade with a spare runner before doing it on a busy pool.