Skip to main content
Version: 3.x

Configuration

The runner is configured with a single YAML file. It is optional: without one, the built-in defaults apply, which are the same as an empty YAML document and safe to run with.

gitea-runner generate-config > config.yaml
gitea-runner -c config.yaml register
gitea-runner -c config.yaml daemon

-c / --config is a global flag and is accepted by every command that loads configuration (register, daemon, cache-server). The generated file is fully commented and is reproduced in Example configuration.

:::warning No environment variable overrides The runner process is configured only through the YAML file. Earlier releases let a few variables (GITEA_DEBUG, GITEA_TRACE, GITEA_RUNNER_CAPACITY, GITEA_RUNNER_FILE, GITEA_RUNNER_ENVIRON, GITEA_RUNNER_ENV_FILE) override parts of the config; those overrides have been removed.

The variables understood by the Docker images belong to their entrypoint, not to the runner, and GITEA_RUNNER_LABELS / GITEA_RUNNER_REGISTRATION_TOKEN are read by the corresponding CLI flags only. :::

Values with a duration type accept Go duration strings such as 30s, 10m, 3h.

log

Controls the runner's own log, not how step output is streamed to the UI.

OptionDefaultDescription
log.levelinfotrace, debug, info, warn, error, fatal or panic. trace and debug add the caller's file:line.

runner

OptionDefaultDescription
file.runnerpath of the registration file. Each runner process needs its own.
capacity1jobs executed concurrently. With an empty container.network, every concurrent docker job takes a subnet from the daemon's address pool, so a high capacity can exhaust it (see default-address-pools in the daemon config).
envsextra environment variables given to every job.
env_file.envsame, read from a file; ignored when empty or missing.
timeout3hmaximum job duration. Gitea has its own timeout (3h by default) and may stop the job earlier.
shutdown_timeout0show long a shutdown waits for running jobs before cancelling them.
insecurefalseskip TLS verification of the Gitea instance.
fetch_timeout5stimeout of a single job fetch.
fetch_interval2sbase polling interval.
fetch_interval_max5supper bound of the exponential backoff applied while idle. 0, or the same value as fetch_interval, disables the backoff.
labelssee Labelslabels used at registration, and by daemon when the flag is absent.
github_mirrorreplaces https://github.com when actions are pulled and the instance's DEFAULT_ACTIONS_URL points at GitHub.
action_shallow_clonetruefetch only the requested ref of an action repository at depth 1 instead of its full history.
set_act_envtrueinject ACT=true into jobs. Set to false so workflows gated on if: ${{ !env.ACT }} behave as they do on GitHub.
allocate_ptyfalseallocate a pseudo-TTY per step. Enable only when a job needs an interactive terminal; tools like docker build then write redrawing progress frames into the log.
workdir_cleanup_age24hage at which stale task workspaces and orphaned host-mode scratch directories are removed while idle.
idle_cleanup_interval10mcadence of the idle cleanup pass. Setting either this or workdir_cleanup_age to 0 disables all idle cleanup.
post_task_scripthost script run after each task's cleanup, see Post-task script.
post_task_script_timeout5mhard limit for that script.
hooks.job_started / hooks.job_completedscripts run inside the job environment, see Job hooks.

Log and state reporting can be tuned when the UI updates too slowly or the instance sees too many requests:

OptionDefaultDescription
log_report_interval5sbase interval of the periodic log flush.
log_report_max_latency3smaximum time a single log row waits. Only has an effect below log_report_interval.
log_report_batch_size100flush immediately once this many rows are buffered, so bursty output arrives promptly.
state_report_interval5sinterval of task state reports. State is also sent on every step transition.
report_close_timeout10sper-attempt deadline for the final log and state flush of a finished job.

Idle cleanup

While no job is running, the runner cleans up after earlier ones:

  • stale task workspaces older than workdir_cleanup_age are removed when container.bind_workdir is enabled. Only purely numeric subdirectories of container.workdir_parent are treated as workspaces, and the path is assumed not to be shared with another runner;
  • orphaned host-mode scratch directories are removed on the same schedule;
  • per-job docker networks left behind by jobs the runner did not live to tear down are removed. They are recognised by the com.gitea.runner.uuid label carrying this runner's uuid, so leftovers of other runners on the same daemon are left alone. Without this, each leaked network keeps holding a subnet of the daemon's address pool.

cache

See Caching for the full picture, including shared cache servers.

OptionDefaultDescription
enabledtruerun the built-in cache server used by actions/cache and friends.
dir$HOME/.cache/actcachewhere cache blobs are stored. Ignored with external_server.
hostaddress job containers use to reach this runner's cache server. Empty means auto-detect; 0.0.0.0 is not valid.
port0port of the built-in server, 0 picks a free one.
external_serverURL of a shared cache-server to use instead of a local one.
external_secretshared secret, required with external_server; must be identical everywhere. Generate with openssl rand -hex 32.
external_secret_fileread that secret from a file instead. Setting both is an error.
offline_modefalsereuse a cached action instead of fetching it on every job. A moved tag or updated branch then stays at the cached commit until the entry expires or is removed.
v2trueserve the cache service v2 API used by actions/cache@v4.2 and later.

container

Applies to jobs that run in containers.

OptionDefaultDescription
networknetwork the job container joins: host, bridge, or a custom network name. Empty means the runner creates one per job. network_mode is still accepted for old configs.
network_create_options.enable_ipv4 / enable_ipv6Docker defaultsonly apply to auto-created networks. IPv6 additionally requires dockerd --ipv6.
privilegedfalserun job containers privileged; required for Docker-in-Docker inside jobs.
optionsextra docker run options, e.g. --add-host=my.gitea.url:host-gateway. A volume declared here replaces the one the runner mounts on the same container path, which is how the tool cache can be kept on the host (--volume /host/toolcache:/opt/hostedtoolcache); its source must also be allowed by valid_volumes.
workdir_parent/workspaceparent directory of a job's working directory inside the container. A leading / is trimmed and re-added.
valid_volumes[]volumes and bind mounts a job may mount, as glob patterns. [] forbids all, ['**'] allows all.
docker_hostoverride the docker host. Empty auto-detects it, - auto-detects it but does not mount the socket into job containers.
force_pullfalsepull images even when present. Images pinned by digest are never re-pulled, and a failed pull with a local copy available only warns.
force_rebuildfalserebuild local action images even when present.
require_dockerfalsealways require a reachable daemon, even for host-only labels.
docker_timeout0show long to wait for the daemon to become reachable.
bind_workdirfalsebind-mount the workspace from the host instead of using a docker volume. Needed for jobs that use docker compose with bind mounts under Docker-in-Docker. The parent directory must then be mounted into the runner container and listed in valid_volumes.

:::note Privileged mode and workflow container options A workflow's own jobs.<job_id>.container.options are untrusted input. While container.privileged is disabled, the options that would break out of the container are stripped with a warning in the job log: --pid, --ipc, --uts, --cgroupns, --userns, --cap-add, --security-opt, --device, --device-cgroup-rule, --gpus, --volumes-from, --runtime, --cgroup-parent and --sysctl. They are honoured once privileged mode is enabled, because the operator has then opted into host access. :::

host

OptionDefaultDescription
host.workdir_parent$HOME/.cache/act/parent directory of a job's working directory for host-mode jobs.

health_check and metrics

Both are covered in Monitoring.

OptionDefaultDescription
health_check.enabledfalsepause fetching new tasks while the machine looks unhealthy.
health_check.min_free_disk_space_mb1024minimum free space on the filesystem holding the workspaces.
health_check.scriptextra executable; a non-zero exit, a timeout or a start failure marks the runner unavailable.
health_check.interval30show long a result is cached.
health_check.timeout10smaximum script runtime.
metrics.enabledfalseserve /metrics, /healthz and /readyz.
metrics.addr127.0.0.1:9101listen address. There is no authentication, so only expose it behind a firewall.
metrics.readiness_grace30show long consecutive polling failures may last before /readyz returns 503.

Reloading

The runner reads its configuration at startup only. Restart the process after a change — with shutdown_timeout set, running jobs are given that much time to finish first.