mirror of
https://gitea.com/gitea/docs.git
synced 2026-11-05 01:25:46 +00:00
Simplify the runner docs and fix their outdated facts (#600)
The runner pages had drifted from the runner. They claimed Podman is unsupported, a registration retry limit of 10, a `container.env` proxy override that has no effect, and they used the deprecated `generate-config` command, while the actual instructions were buried under implementation details. The develop and 5.x pages are rewritten from the current runner sources (`main` is `v5.2.0`). They are shorter and aimed at operators, with a new page covering what jobs get. The reference generator now documents the `config` command, and the quickstart pages in every language use the `gitea-runner` binary name. Reviewed-on: https://gitea.com/gitea/docs/pulls/600 Reviewed-by: Lunny Xiao <[email protected]> Co-authored-by: silverwind <[email protected]>
This commit is contained in:
1 parent
a874918bb7
commit
be6aefc7e8
53 files changed
+1531
-1661
No files matched your search
@@ -4,120 +4,74 @@ sidebar_position: 2
|
||||
|
||||
# Install with Docker
|
||||
|
||||
The official images are published on [Docker Hub](https://hub.docker.com/r/gitea/runner/tags) as `docker.io/gitea/runner`.
|
||||
`latest` is the newest release and the `5` tag follows the newest `5.x` release; `nightly` is built from the `main` branch, and every release is also tagged with its exact version.
|
||||
|
||||
In the container the registration and the daemon are combined: the entrypoint registers the runner on first start (when no registration file exists yet) and then execs `gitea-runner daemon`.
|
||||
|
||||
## Image flavours
|
||||
|
||||
All flavours contain the same `gitea-runner` binary and differ only in how a Docker daemon is made available to jobs.
|
||||
|
||||
| Tag | Base image | Docker daemon | Supervisor | Runs as |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `latest`, `5`, `5.1`, `<version>` | `alpine` | none, you provide one | `tini` | `root` |
|
||||
| `latest-dind`, `5-dind` | `docker:dind` | bundled, needs `--privileged` | `s6` | `root` |
|
||||
| `latest-dind-rootless`, `5-dind-rootless` | `docker:dind-rootless` | bundled, rootless | `s6` | `rootless` (UID 1000) |
|
||||
|
||||
The rootless flavour's UID is fixed at 1000 by the upstream base image, and its daemon always listens on `/run/user/1000/docker.sock`, so `--user 1001` does not work. To talk to a *host* rootless daemon under another UID, use the basic flavour and bind-mount that daemon's socket instead.
|
||||
|
||||
## Basic flavour
|
||||
|
||||
The default image ships no daemon of its own, so jobs that use `docker://` images need one from outside the container — usually the host's socket:
|
||||
Runner images are available on [Docker Hub](https://hub.docker.com/r/gitea/runner/tags) as `docker.io/gitea/runner`. On its first start, the container registers and starts the runner:
|
||||
|
||||
```bash
|
||||
docker run -d --name my_runner \
|
||||
-e GITEA_INSTANCE_URL=<instance_url> \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token> \
|
||||
-e GITEA_RUNNER_NAME=<runner_name> \
|
||||
-v $PWD/data:/data \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
docker.io/gitea/runner:5
|
||||
```
|
||||
|
||||
This flavour does not need `--privileged`. The trade-off is that jobs share the host's daemon and can therefore see its other containers and images. A job that can reach the socket can also read the reusable `GITEA_RUNNER_REGISTRATION_TOKEN` from the runner container's `docker inspect` output.
|
||||
|
||||
## Docker-in-Docker
|
||||
|
||||
The `dind` flavour bundles its own daemon, so no socket has to be mounted:
|
||||
|
||||
```bash
|
||||
docker run -d --name my_runner --privileged \
|
||||
-e GITEA_INSTANCE_URL=<instance_url> \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token> \
|
||||
-v $PWD/data:/data \
|
||||
docker run -d --name gitea-runner --restart always --privileged \
|
||||
-e GITEA_INSTANCE_URL=https://gitea.example.com \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<token> \
|
||||
-v ./data:/data \
|
||||
-v runner-docker:/var/lib/docker \
|
||||
docker.io/gitea/runner:5-dind
|
||||
```
|
||||
|
||||
`s6` starts `dockerd` first and the runner service waits for it before registering. Use `5-dind-rootless` to run both the daemon and the runner as an unprivileged user; rootless Docker's usual limitations around networking, cgroups and storage drivers apply.
|
||||
The `-dind` image runs its own Docker daemon for jobs. Jobs never get access to the host's Docker daemon socket, which grants the equivalent of root access on the host. The two volumes preserve registration and job images when you replace the container:
|
||||
|
||||
## Volumes
|
||||
- `/data` holds the `.runner` registration file. Without it, a new container registers as another runner.
|
||||
- `/var/lib/docker` holds the images pulled for jobs. Without it, a new container pulls them again.
|
||||
|
||||
Two different pieces of state are worth persisting, and neither implies the other:
|
||||
## Image flavours
|
||||
|
||||
- `/data` is the runner's working directory. It holds the `.runner` registration file and, optionally, the config file. Without it, a recreated container registers itself again as a new runner, leaving a stale entry in Gitea, and fails outright if the token has been reset in the meantime.
|
||||
- the Docker daemon's data root holds the images pulled for jobs. It is **not** under `/data`: for `dind` it is `/var/lib/docker` inside the container, for `dind-rootless` it is `/home/rootless/.local/share/docker`. Give it its own volume, or every new container re-pulls the job images.
|
||||
| Tag | Docker daemon for jobs |
|
||||
| --- | --- |
|
||||
| `5-dind` (recommended) | Bundled. Requires `--privileged`. |
|
||||
| `5-dind-rootless` | Bundled. Runs as UID 1000. Requires `--privileged` and [rootless Docker](https://docs.docker.com/engine/security/rootless/) support on the host. Stores its images in `/home/rootless/.local/share/docker`. |
|
||||
| `5` | None. Mount the host's Docker daemon socket with `-v /var/run/docker.sock:/var/run/docker.sock`, or set `DOCKER_HOST`. |
|
||||
|
||||
## Entrypoint environment variables
|
||||
The `5` tags follow the newest `5.x` release. The `latest` and exact version tags such as `5.2.0` use the same suffixes. The `-dind` flavours are available for amd64 and arm64. The basic image also supports riscv64 and s390x. The images are designed for Docker, not Podman.
|
||||
|
||||
The entrypoint ([`scripts/run.sh`](https://gitea.com/gitea/runner/src/branch/main/scripts/run.sh)) understands:
|
||||
When the basic image uses the host's Docker daemon, jobs share that daemon. Use this setup only for trusted repositories.
|
||||
|
||||
## Environment variables
|
||||
|
||||
| Variable | Meaning |
|
||||
| --- | --- |
|
||||
| `GITEA_INSTANCE_URL` | instance to register against, e.g. `https://gitea.example.com/` |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN` | registration token; unset before the daemon starts |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN_FILE` | file to read the token from, for Docker/Kubernetes secrets |
|
||||
| `GITEA_RUNNER_NAME` | runner name, defaults to the container hostname |
|
||||
| `GITEA_RUNNER_LABELS` | labels, passed to both `register` and `daemon` |
|
||||
| `GITEA_RUNNER_EPHEMERAL` | any non-empty value registers the runner as [ephemeral](../registration.md#ephemeral-runners) |
|
||||
| `GITEA_RUNNER_ONCE` | any non-empty value runs a single job, then exits |
|
||||
| `GITEA_MAX_REG_ATTEMPTS` | registration attempts before giving up, default `10` |
|
||||
| `RUNNER_STATE_FILE` | registration file name inside `/data`, default `.runner` |
|
||||
| `CONFIG_FILE` | config file inside the container, passed as `--config` |
|
||||
| `GITEA_INSTANCE_URL` | Gitea instance to register with. |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN` | Registration token, needed only until registration completes. |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN_FILE` | File to read the registration token from, such as a Docker secret. |
|
||||
| `GITEA_RUNNER_NAME` | Runner name. Defaults to the container's hostname. |
|
||||
| `GITEA_RUNNER_LABELS` | Comma-separated [labels](../labels.md), applied on every start. |
|
||||
| `GITEA_RUNNER_EPHEMERAL` | Any nonempty value registers an [ephemeral runner](../registration.md#ephemeral-runners). |
|
||||
| `GITEA_RUNNER_ONCE` | Any nonempty value makes the runner exit after one job. |
|
||||
| `GITEA_MAX_REG_ATTEMPTS` | Maximum number of registration attempts. Unlimited by default, with 5 seconds between attempts. |
|
||||
| `CONFIG_FILE` | Path to a [configuration file](../configuration.md) inside the container. |
|
||||
|
||||
These are entrypoint variables, not runner settings: the runner process itself is configured only through the [config file](../configuration.md).
|
||||
|
||||
Mount the config file when you need one:
|
||||
To use a configuration file, mount it and set `CONFIG_FILE` to its path:
|
||||
|
||||
```bash
|
||||
docker run -v $PWD/config.yaml:/config.yaml -e CONFIG_FILE=/config.yaml ...
|
||||
docker run ... -v ./config.yaml:/config.yaml -e CONFIG_FILE=/config.yaml docker.io/gitea/runner:5-dind
|
||||
```
|
||||
|
||||
A config file can be generated with the image itself:
|
||||
|
||||
```bash
|
||||
docker run --rm --entrypoint="" docker.io/gitea/runner:5 gitea-runner generate-config > config.yaml
|
||||
```
|
||||
|
||||
## docker compose
|
||||
## Docker Compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
runner:
|
||||
image: docker.io/gitea/runner:5
|
||||
image: docker.io/gitea/runner:5-dind
|
||||
restart: always
|
||||
privileged: true
|
||||
environment:
|
||||
CONFIG_FILE: /config.yaml
|
||||
GITEA_INSTANCE_URL: "${INSTANCE_URL}"
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: "${REGISTRATION_TOKEN}"
|
||||
GITEA_RUNNER_NAME: "${RUNNER_NAME}"
|
||||
GITEA_RUNNER_LABELS: "${RUNNER_LABELS}"
|
||||
GITEA_INSTANCE_URL: https://gitea.example.com
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: <token>
|
||||
volumes:
|
||||
- ./config.yaml:/config.yaml
|
||||
- ./data:/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- runner-docker:/var/lib/docker
|
||||
|
||||
volumes:
|
||||
runner-docker:
|
||||
```
|
||||
|
||||
When Gitea runs in the same compose project, depend on its health check so the runner does not try to register before the instance answers:
|
||||
|
||||
```yaml
|
||||
depends_on:
|
||||
gitea:
|
||||
condition: service_healthy
|
||||
restart: true
|
||||
```
|
||||
|
||||
The rootless Docker-in-Docker variant needs a few extra options:
|
||||
The rootless flavour needs these additional settings:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -126,22 +80,21 @@ services:
|
||||
restart: always
|
||||
privileged: true
|
||||
security_opt:
|
||||
# for hosts running AppArmor (Ubuntu, Debian), whose default profile blocks
|
||||
# the user namespace changes the bundled daemon needs
|
||||
- apparmor=rootlesskit
|
||||
volumes:
|
||||
- ./data/runner:/data
|
||||
environment:
|
||||
- GITEA_INSTANCE_URL=<instance_url>
|
||||
- GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token>
|
||||
- DOCKER_HOST=unix:///var/run/user/1000/docker.sock
|
||||
# slirp4netns gives significantly better network throughput than vpnkit
|
||||
- DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns
|
||||
- DOCKERD_ROOTLESS_ROOTLESSKIT_MTU=65520
|
||||
GITEA_INSTANCE_URL: https://gitea.example.com
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: <token>
|
||||
DOCKERD_ROOTLESS_ROOTLESSKIT_NET: slirp4netns
|
||||
DOCKERD_ROOTLESS_ROOTLESSKIT_MTU: 65520
|
||||
volumes:
|
||||
- runner-data:/data
|
||||
|
||||
volumes:
|
||||
runner-data:
|
||||
```
|
||||
|
||||
## Cache from a dockerized runner
|
||||
- Set `security_opt` on AppArmor hosts such as Ubuntu and Debian. Docker's `docker-ce-rootless-extras` package provides the `rootlesskit` profile.
|
||||
- Use `slirp4netns` for better job network throughput than the default.
|
||||
- Make `/data` writable by UID 1000. Use a named volume or a bind-mounted host directory owned by that UID.
|
||||
|
||||
A runner in a container creates a separate network per job by default, so the address it detects for its own cache server is often unreachable from job containers and `actions/cache` fails with a connection timeout. Set `cache.host` and `cache.port` explicitly and publish that port, or put the job containers on a shared network — see [Caching](../cache.md#dockerized-runners).
|
||||
|
||||
More deployment examples live in the [`examples`](https://gitea.com/gitea/runner/src/branch/main/examples) directory of the runner repository.
|
||||
See the runner repository's [examples](https://gitea.com/gitea/runner/src/branch/main/examples) for more deployments.
|
||||
Reference in new issue
Block a user