initial commit

This commit is contained in:
Worph
2026-10-03 16:09:47 +02:00
commit b5224cb512
25 changed files with 1804 additions and 0 deletions
+408
View File
@@ -0,0 +1,408 @@
name: gitea
services:
# Gitea itself — git hosting, the Actions controller, and the OCI package
# registry, all in one process. SQLite: a personal forge never has the write
# concurrency that would justify a second container for Postgres.
gitea:
image: gitea/gitea:1.27.3-rootless
container_name: gitea
user: $PUID:$PGID
restart: unless-stopped
cpu_shares: 70
deploy:
resources:
limits:
memory: 1G
environment:
TZ: $TZ
# Every URL Gitea hands out — clone URLs, the registry host, and the
# server_url the CI runner passes to jobs — is derived from ROOT_URL, so
# it has to be the address that works from outside as well as inside.
GITEA__server__ROOT_URL: https://gitea-${APP_DOMAIN}/
GITEA__server__DOMAIN: gitea-${APP_DOMAIN}
GITEA__server__HTTP_PORT: "3000"
GITEA__server__PROTOCOL: http
# The address Gitea's own CLI uses to reach the running server's internal
# API. It defaults to localhost, which is right for the server itself and
# useless from the init container that runs
# `gitea actions generate-runner-token`. It has to be set here rather than
# there: the CLI reads it out of the shared app.ini, and only this
# container's entrypoint renders environment into app.ini.
GITEA__server__LOCAL_ROOT_URL: http://gitea:3000/
# Git over SSH would need a published host port of its own. Everything
# here — clone, push, CI, registry — goes over HTTPS instead.
GITEA__server__DISABLE_SSH: "true"
GITEA__server__START_SSH_SERVER: "false"
# Skips the first-run install wizard: every value it would ask for is set
# here, and the admin account is created by an init step below.
GITEA__security__INSTALL_LOCK: "true"
GITEA__database__DB_TYPE: sqlite3
GITEA__database__PATH: /var/lib/gitea/data/gitea.db
GITEA__service__DISABLE_REGISTRATION: "true"
GITEA__service__REQUIRE_SIGNIN_VIEW: "true"
GITEA__actions__ENABLED: "true"
# Where a bare `uses: actions/checkout@v4` is resolved from.
GITEA__actions__DEFAULT_ACTIONS_URL: github
GITEA__packages__ENABLED: "true"
# Lets a pull mirror name a repository on this server's own Docker
# network — a Radicle node's git endpoint, for instance. See rationale.md.
GITEA__migrations__ALLOW_LOCALNETWORKS: "true"
# How often a pull mirror is re-fetched. The sync emits the same push
# event a real push would, so this interval is also how quickly CI
# reacts to a commit that arrives from the mirrored source.
GITEA__mirror__DEFAULT_INTERVAL: 10m
GITEA__mirror__MIN_INTERVAL: 10m
volumes:
- ${DATA_ROOT:-/DATA}/AppData/$AppID/data:/var/lib/gitea
- ${DATA_ROOT:-/DATA}/AppData/$AppID/config:/etc/gitea
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000/api/healthz"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
expose:
- 3000
labels:
caddy_0: gitea-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 3000}}"
caddy_1: gitea-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 3000}}"
caddy_2: gitea-${APP_PUBLIC_IP_DASH}.sslip.io
caddy_2.reverse_proxy: "{{upstreams 3000}}"
networks:
- pcs
- gitea-internal
# The CI runner: act_runner with its own Docker daemon inside it (dind), so
# workflow jobs and the images they build never touch the host's daemon.
# See rationale.md for what `privileged` buys and what it costs.
gitea-runner:
image: gitea/act_runner:0.6.1-dind
container_name: gitea-runner
restart: unless-stopped
privileged: true
cpu_shares: 20
deploy:
resources:
limits:
memory: 2G
environment:
TZ: $TZ
# This address is not just how the runner daemon reaches Gitea — it is
# handed to every job as GITHUB_SERVER_URL, and a job runs inside the
# runner's *nested* daemon, on a network where `gitea` does not resolve.
# So it has to be an address that works from the outside: checkout and
# `docker login` from a workflow both go out and back over HTTPS.
GITEA_INSTANCE_URL: https://gitea-${APP_DOMAIN}
GITEA_RUNNER_REGISTRATION_TOKEN_FILE: /data/token
GITEA_RUNNER_NAME: gitea-runner
# Registration-time labels. runner-config/config.yaml repeats them, and
# that copy wins on every start, so an installed runner follows store updates.
GITEA_RUNNER_LABELS: ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest,ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04,ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04,docker:docker://docker:28.5-cli
CONFIG_FILE: /config/config.yaml
# DOCKER_TLS_CERTDIR is deliberately left at the image's default. Emptying
# it does not turn the nested daemon's TCP listener off — it turns the
# listener's TLS off, and 2375 then answers unauthenticated to anything
# that can reach this container.
volumes:
# .runner (the registration this runner is identified by) and the
# registration token the init step leaves for it.
- ${DATA_ROOT:-/DATA}/AppData/$AppID/runner:/data
- ${DATA_ROOT:-/DATA}/AppData/$AppID/runner-config:/config:ro
# Replaces the image's own start-up wait — see the comments in the
# script. It is declared under x-compose-app.files rather than left to
# the seed tree, because it has to arrive executable.
- ${DATA_ROOT:-/DATA}/AppData/$AppID/runner-config/act_runner-run:/etc/s6/act_runner/run:ro
# The inner daemon's image store. Without this every restart re-pulls
# every base image a workflow uses.
- ${DATA_ROOT:-/DATA}/AppData/$AppID/runner-docker:/var/lib/docker
networks:
- gitea-internal
networks:
pcs:
name: ${APP_NET:-pcs}
external: true
# The runner has no business being reachable from other apps — it only ever
# talks to gitea and to the internet.
gitea-internal:
driver: bridge
x-casaos:
architectures:
- amd64
main: gitea
developer: Gitea
category: Developer
tags: ["developer", "git", "ci"]
description:
en_us: |
Gitea — a git forge with CI and a container registry
Gitea is a lightweight, self-contained software forge: repositories, issues, pull requests, releases, a CI engine and an OCI container registry in a single service that is happy on a small machine.
What it gives you here:
• Git hosting over HTTPS, with issues, pull requests, releases and wikis
• Actions — CI workflows in GitHub Actions syntax, so existing workflow files usually run unchanged
• A built-in container registry, so a workflow can build an image and push it next to the code it came from
• Pull mirrors — point a repository at any git URL and it is re-fetched on a schedule, and each sync starts the same workflows a push would
That last pair is what makes it useful in front of a git source that has no webhooks of its own: mirror the repository, and the mirror's own updates drive the build.
A runner ships with the app, with its own Docker daemon inside it, so workflows can build container images out of the box.
fr_fr: |
Gitea — une forge git avec CI et registre de conteneurs
Gitea est une forge logicielle légère et autonome : dépôts, tickets, pull requests, versions, moteur d'intégration continue et registre de conteneurs OCI dans un seul service, à l'aise sur une petite machine.
Ce que vous obtenez ici :
• Hébergement git en HTTPS, avec tickets, pull requests, versions et wikis
• Actions — des workflows d'intégration continue en syntaxe GitHub Actions, si bien qu'un fichier de workflow existant tourne généralement tel quel
• Un registre de conteneurs intégré : un workflow peut construire une image et la publier à côté du code dont elle provient
• Miroirs — pointez un dépôt vers n'importe quelle URL git, il est re-synchronisé périodiquement, et chaque synchronisation déclenche les mêmes workflows qu'un push
Ces deux derniers points sont ce qui rend Gitea utile devant une source git dépourvue de webhooks : mettez le dépôt en miroir, et ce sont les mises à jour du miroir qui pilotent la construction.
Un runner est fourni avec l'application, avec son propre démon Docker embarqué, afin que les workflows puissent construire des images de conteneurs dès l'installation.
zh_cn: |
Gitea — 带 CI 与容器仓库的 Git 代码托管
Gitea 是轻量、自足的软件协作平台:仓库、议题、合并请求、发布、CI 引擎与 OCI 容器仓库集于一个服务,在小型机器上也能流畅运行。
它在这里提供:
• 通过 HTTPS 托管 Git,附带议题、合并请求、发布与百科
• Actions —— 采用 GitHub Actions 语法的 CI 工作流,现有的工作流文件通常无需修改即可运行
• 内置容器仓库,工作流可以构建镜像并发布在源代码旁边
• 拉取镜像同步 —— 将仓库指向任意 Git URL,它会按计划重新拉取,每次同步都会触发与推送相同的工作流
后两项让 Gitea 特别适合放在没有 webhook 的 Git 源前面:把仓库设为镜像,镜像的更新就会驱动构建。
应用自带一个运行器,内含独立的 Docker 守护进程,因此工作流开箱即可构建容器镜像。
icon: icon.png
screenshot_link:
- screenshot-1.png
- screenshot-2.png
- screenshot-3.png
thumbnail: thumbnail.png
tagline:
en_us: A git forge with CI and a container registry, on your own domain.
fr_fr: Une forge git avec intégration continue et registre de conteneurs, sur votre domaine.
zh_cn: 运行在你自己域名下的 Git 托管,内建 CI 与容器仓库。
tips:
before_install:
en_us: |
Signing in
| | |
| --- | --- |
| Address | `https://gitea-$APP_DOMAIN` |
| User | `gitea_admin` |
| Password | your server's default app password |
Gitea uses its own account system. Self-registration is off, so
`gitea_admin` is the only account until you create more under
Site Administration.
Building from a repository that has no webhooks
New Migration → check **This repository will be a mirror**, and give it
the git URL. Gitea re-fetches on a schedule, and each sync raises the
same `push` event a real push would — so a workflow with `on: push`
runs. Commit the workflow to `.gitea/workflows/` in the mirrored
repository itself (`.github/workflows/` also works; `.forgejo/` does
not).
One thing to change by hand: a migrated repository arrives with
**Actions switched off**. Repository → Settings → Advanced Settings →
tick **Actions**, or nothing will ever run, however correct the
workflow is.
Publishing images
The registry lives at the same address as the web UI. In a workflow,
log in to `gitea-$APP_DOMAIN` and push to
`gitea-$APP_DOMAIN/<user>/<image>:<tag>`. Use an access token with the
`write:package` scope, kept as a repository secret — the token Actions
injects as `secrets.GITHUB_TOKEN` is rejected by the registry.
The CI runner
The runner holds a Docker daemon of its own and therefore runs
privileged. It is what lets a workflow build container images. If you
do not intend to run CI, stop the `gitea-runner` container — Gitea
itself is unaffected.
fr_fr: |
Connexion
| | |
| --- | --- |
| Adresse | `https://gitea-$APP_DOMAIN` |
| Utilisateur | `gitea_admin` |
| Mot de passe | le mot de passe par défaut de vos applications |
Gitea gère ses propres comptes. L'auto-inscription est désactivée :
`gitea_admin` est donc le seul compte tant que vous n'en créez pas
d'autres depuis l'administration du site.
Construire depuis un dépôt sans webhooks
Nouvelle migration → cochez **Ce dépôt sera un miroir** et indiquez
l'URL git. Gitea re-synchronise périodiquement, et chaque
synchronisation lève l'événement `push` qu'un vrai push aurait levé —
un workflow `on: push` se déclenche donc. Le fichier de workflow se
place dans `.gitea/workflows/` du dépôt mis en miroir
(`.github/workflows/` fonctionne aussi ; `.forgejo/` non).
Une chose à changer à la main : un dépôt migré arrive avec **Actions
désactivé**. Dépôt → Paramètres → Paramètres avancés → cochez
**Actions**, sinon rien ne se déclenchera, si correct que soit le
workflow.
Publier des images
Le registre est à la même adresse que l'interface web. Dans un
workflow, connectez-vous à `gitea-$APP_DOMAIN` puis publiez vers
`gitea-$APP_DOMAIN/<utilisateur>/<image>:<tag>`. Utilisez un jeton
d'accès de portée `write:package`, conservé en secret de dépôt : le
jeton fourni par Actions (`secrets.GITHUB_TOKEN`) est refusé par le
registre.
Le runner d'intégration continue
Le runner embarque son propre démon Docker et tourne donc en mode
privilégié. C'est ce qui permet à un workflow de construire des images
de conteneurs. Si vous ne comptez pas utiliser l'intégration continue,
arrêtez le conteneur `gitea-runner` — Gitea lui-même n'en dépend pas.
zh_cn: |
登录
| | |
| --- | --- |
| 地址 | `https://gitea-$APP_DOMAIN` |
| 用户 | `gitea_admin` |
| 密码 | 服务器的默认应用密码 |
Gitea 使用自己的账户体系。自助注册已关闭,因此在你于站点管理中创建更多账户之前,
`gitea_admin` 是唯一的账户。
为没有 webhook 的仓库构建
新建迁移 → 勾选**将此仓库设为镜像**并填入 git URL。Gitea 会按计划重新拉取,
每次同步都会触发与真实推送相同的 `push` 事件,因此 `on: push` 工作流会运行。
工作流文件请提交到被镜像仓库自身的 `.gitea/workflows/` 目录
(`.github/workflows/` 同样有效,`.forgejo/` 无效)。
有一处需要手动调整:迁移而来的仓库默认**关闭 Actions**。
进入 仓库 → 设置 → 高级设置 → 勾选 **Actions**,否则工作流再正确也不会运行。
发布镜像
容器仓库与网页界面位于同一地址。在工作流中登录 `gitea-$APP_DOMAIN`,
并推送到 `gitea-$APP_DOMAIN/<用户>/<镜像>:<标签>`。请使用具有
`write:package` 权限的访问令牌并存为仓库机密 —— Actions 注入的
`secrets.GITHUB_TOKEN` 会被容器仓库拒绝。
CI 运行器
运行器内含独立的 Docker 守护进程,因此以特权模式运行,这正是工作流能够构建
容器镜像的原因。若不打算使用 CI,可停止 `gitea-runner` 容器 —— 这不影响 Gitea 本身。
title:
en_us: Gitea
index: /
webui_port: 3000
store_app_id: gitea
x-compose-app:
schema_version: 2
folders:
- path: /DATA/AppData/$AppID/data
user: $PUID
group: $PGID
- path: /DATA/AppData/$AppID/config
user: $PUID
group: $PGID
# Holds .runner (the runner's registration) and the token file the
# init step writes for it.
- path: /DATA/AppData/$AppID/runner
user: $PUID
group: $PGID
mode: "0700"
- path: /DATA/AppData/$AppID/runner-config
user: $PUID
group: $PGID
# The inner Docker daemon's image store. dockerd runs as root inside the
# runner and takes ownership of what it creates below this point.
- path: /DATA/AppData/$AppID/runner-docker
user: $PUID
group: $PGID
mode: "0710"
files:
# Declared rather than left to the seed tree so the executable bit is
# stated, not inherited: git on a Windows-hosted checkout records every
# file 100644, and s6 refuses to spawn a `run` script it cannot execute —
# the runner then loops "unable to spawn ./run: Permission denied" and no
# workflow ever runs.
- path: /DATA/AppData/$AppID/runner-config/act_runner-run
from: runner-config/act_runner-run
ensure: always
mode: "0755"
init:
# Both steps are the gitea binary acting on its own installation, and both
# have to wait for the server: post_up fires as soon as `compose up`
# returns, which is when the container has *started*, not when Gitea has
# migrated its schema. Run them any sooner and `user create` dies on
# "no such table: user".
#
# The wait is bounded by `timeout` rather than left open: a step that
# blocks forever would hold the install open forever.
- name: create-admin
image: gitea/gitea:1.27.3-rootless
user: $PUID:$PGID
phase: post_up
volumes:
- /DATA/AppData/$AppID/data:/var/lib/gitea
- /DATA/AppData/$AppID/config:/etc/gitea
command:
- sh
- -c
- |
timeout 240 sh -c 'until gitea admin user list >/dev/null 2>&1; do sleep 3; done'
gitea admin user create --admin --username gitea_admin \
--password "$APP_DEFAULT_PASSWORD" --email "$APP_EMAIL" \
--must-change-password=false \
|| echo "admin account already present, leaving it alone"
# Re-run rather than remembered: the command is idempotent, and an account
# that was deleted by accident comes back on the next start.
when: always
- name: runner-token
image: gitea/gitea:1.27.3-rootless
user: $PUID:$PGID
phase: post_up
# Unlike the account, a runner token is not a database write — it is a
# call to the running server's internal API, so this one needs to be able
# to reach it.
network: $APP_NET
volumes:
- /DATA/AppData/$AppID/data:/var/lib/gitea
- /DATA/AppData/$AppID/config:/etc/gitea
- /DATA/AppData/$AppID/runner:/runner
command:
- sh
- -c
- |
timeout 240 sh -c 'until gitea actions generate-runner-token > /runner/token.new 2>/dev/null; do sleep 3; done'
mv /runner/token.new /runner/token
chmod 600 /runner/token
# Only while the runner has no registration of its own. Once it has one
# the token is dead weight, and re-minting it on every start would leave
# a live credential lying in the app folder for no reason.
when: absent:/DATA/AppData/$AppID/runner/.runner
webui-host: gitea-${domain}
webui-path: /
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

+86
View File
@@ -0,0 +1,86 @@
# Gitea — Rationale
## What deviation / exception is being requested
1. `gitea-runner` runs with `privileged: true`.
2. Gitea is configured with `[migrations] ALLOW_LOCALNETWORKS = true`.
3. The admin account is called `gitea_admin`, not the deployment's usual `admin`.
## Why it is necessary
**1. The privileged runner.** The point of shipping a runner at all is that a
workflow can build a container image. That needs a Docker daemon, and there are
only two ways to give a CI job one:
- mount the host's `/var/run/docker.sock` into the runner, which hands every
workflow — including one that arrives from a mirrored third-party repository —
full control of the host's daemon, i.e. root on the PCS; or
- give the runner a daemon of its own inside the container (`dind`), which
requires `privileged`.
The second is the smaller exposure: the blast radius is the runner's own
container and its own image store, not the host's containers, volumes and
socket. It is also what upstream ships the `-dind` tag for.
The rootless dind variant (`0.6.1-dind-rootless`) would have avoided
`privileged` altogether, and was tried first. It does not start on this
platform: Ubuntu sets `kernel.apparmor_restrict_unprivileged_userns=1`, and
rootlesskit dies with `fork/exec /proc/self/exe: operation not permitted`.
Making it work means turning that protection off for the container
(`security_opt: apparmor=unconfined`), which weakens the host more than
`privileged` on a single container does. Revisit if the platform ever ships
that sysctl relaxed, or if upstream's runner learns to use the host's
user-namespace remapping.
**2. `ALLOW_LOCALNETWORKS`.** Gitea refuses by default to migrate or mirror
from an address on a private network. The app's most useful configuration —
mirroring a repository from another app on the same server, e.g. a Radicle
node's git endpoint at `http://radicle-api:8080/<rid>.git` — is exactly that
case. Without the flag the URL is rejected before any fetch is attempted.
**3. The admin username.** `admin` is on Gitea's reserved-name list (it
collides with the `/admin` route) and account creation fails with it.
## Security mitigations in place
- The runner is not on the shared `pcs` network. It sits on an app-internal
bridge with Gitea and nothing else, so no other app can reach it, and it
publishes no port.
- The runner's daemon is nested: its image store is a directory under the
app's own AppData, and the containers it creates are invisible to, and
cannot see, the host's daemon.
- `capacity: 1` in the runner config and a 2G memory limit bound what a
runaway build can consume.
- Self-registration is disabled (`DISABLE_REGISTRATION`) and anonymous
browsing is off (`REQUIRE_SIGNIN_VIEW`), so the forge starts closed with a
single account whose password is the deployment's default app password.
- `ALLOW_LOCALNETWORKS` is reachable only by an authenticated user of this
Gitea — with registration disabled, that is the owner. It widens what the
owner can point a mirror at; it does not expose anything to an anonymous
caller.
- The runner is severable: stopping the `gitea-runner` container leaves a
fully working forge and removes the privileged container from the box. This
is called out in `tips.before_install`.
## Alternatives considered and rejected
| Alternative | Why not |
|---|---|
| Host Docker socket in the runner | Any workflow, including one from a mirrored repo, gets root on the host. Strictly worse than a privileged container. |
| `0.6.1-dind-rootless` | Does not start under Ubuntu's unprivileged-userns restriction (see above); the workaround disables AppArmor for the container. |
| Ship no runner | Gitea Actions is the reason to choose Gitea over a plain git server here, and a runner cannot be added later without the same `privileged` decision. |
| Mirror over the public HTTPS address instead of `ALLOW_LOCALNETWORKS` | Works, but routes a same-box fetch out to the gateway and back, and breaks if the deployment has no public address. |
## Data protection
Everything that survives a restart is under `/DATA/AppData/gitea/`:
repositories and the SQLite database in `data/`, the rendered `app.ini` in
`config/`, the runner's registration in `runner/`, and the nested daemon's
image store in `runner-docker/`. Nothing is written outside that tree, and no
user directory (`/DATA/Documents`, `/DATA/Media`, …) is mounted into any
container.
The only credential the app generates is the runner registration token, which
is rewritten on every start and is worthless without network access to Gitea.
The admin password is the deployment's own `APP_DEFAULT_PASSWORD`; it is never
written to disk by this app beyond Gitea's own salted hash.
Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Replaces the image's own /etc/s6/act_runner/run. Two waits, both of which the
# stock script gets wrong for this deployment.
#
# 1. The nested Docker daemon. Upstream waits for it through s6's readiness
# notification. On a cold start with a warm image store dockerd takes longer
# than s6-notifyoncheck's window, the notification never arrives, s6 marks
# the service permanently failed, and act_runner sits blocked in
# `s6-svwait -U` for two to four minutes before s6 gives up and lets it past
# anyway. The runner shows "offline" in the forge for that whole time and
# picks up no jobs. Asking the daemon directly is the same wait without the
# guesswork.
#
# 2. The registration token. It is minted by an init step that runs after the
# stack is up, so on a first install it does not exist yet when this
# container starts — and the stock entrypoint reads the token file exactly
# once, before its retry loop, so a token that arrives late is never seen.
while [ ! -d /etc/s6/docker/supervise ]; do
sleep 0.1
done
while ! docker info >/dev/null 2>&1; do
sleep 1
done
while [ ! -s "${GITEA_RUNNER_REGISTRATION_TOKEN_FILE:-/data/token}" ] && [ ! -s /data/.runner ]; do
echo "waiting for the runner registration token"
sleep 2
done
exec run.sh
+40
View File
@@ -0,0 +1,40 @@
# act_runner configuration. Only the settings that differ from upstream's
# defaults are written out — `act_runner generate-config` prints the full set.
log:
level: info
runner:
# The file the runner's own registration is kept in, relative to /data.
file: .runner
# One job at a time. A PCS shares its CPU with everything else installed on
# it, and an image build is the least polite thing on the box.
capacity: 1
timeout: 1h
fetch_timeout: 5s
fetch_interval: 2s
# Overrides the labels stored at registration (.runner). These are upstream
# act_runner defaults: Gitea's own job images, which carry node, bash, git
# and the docker CLI with buildx, so marketplace actions (actions/checkout,
# docker/build-push-action, ...) run as they do on GitHub. The registration
# labels pointed at node:22-bookworm, which has no docker CLI.
labels:
- "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
- "ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04"
- "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"
- "docker:docker://docker:28.5-cli"
cache:
# The cache server binds an address inside the runner container, which the
# job containers — created by the Docker daemon nested inside that same
# container — cannot route to. Left on, every `actions/cache` step fails
# noisily instead of being skipped.
enabled: false
container:
# Jobs run on the runner's own nested daemon, on its default bridge: they
# reach the internet, and they reach Gitea the way anything outside would,
# through its public address.
network: bridge
privileged: false
force_pull: false
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB