Use an isolated network per Gitea Actions job

Job containers were pinned to a single shared `gitea-actions` bridge
network, added with the Actions cache to give service containers DNS and a
fixed gateway for the built-in cache server. Because every job of every run
attached to that one network, concurrent jobs' service containers collided
on hostnames: two simultaneous jobs that both expose a `redis` service meant
either could resolve the other's container, causing intermittent cross-job
CI failures that vanished when runs did not overlap.

Set `container.network` back to empty so the runner auto-creates an isolated
user-defined network per job. Embedded DNS still works on each per-job
network, so service containers remain reachable by name, but jobs can no
longer resolve each other's containers.

`cache.host` is left empty for auto-detection; the runner here is a host
binary (systemd), not containerized, so the detected address is reachable
from job containers. The cache port stays fixed per runner. The cache
firewall rule now allows Docker's default address pool (172.16.0.0/12)
because per-job subnets are dynamic, and the now-unused `gitea-actions`
network is removed on converge once idle.
This commit is contained in:
raucao committed 2026-11-03 20:46:50 +04:00
1 parent 3883fbc3e5
commit 8a60ef2aea
4 files changed
+28 -7

No files matched your search

+10
View File
@@ -2,6 +2,16 @@
This file is used to list changes made in each version of the kosmos_gitea cookbook.
# 0.3.5
- Stop pinning job containers to one shared Docker network. `container.network`
is empty again, so the runner auto-creates an isolated bridge network per job:
concurrent jobs keep service-container DNS (e.g. `redis`) but can no longer
resolve each other's service containers, fixing intermittent cross-job CI
failures. `cache.host` is auto-detected, and the cache firewall rule now allows
Docker's default address pool (`172.16.0.0/12`).
- Remove the now-unused `gitea-actions` network on converge (once idle).
# 0.3.4
- Upgrade the Gitea Actions runner from 5.0.0 to 5.2.2. No `config.yaml` changes
@@ -32,11 +32,17 @@ node.default["gitea"]["runner"]["config"] = {
"capacity" => 2
},
"container" => {
"network" => "gitea-actions" # User-defined bridge network: provides DNS for service containers
# Empty: the runner auto-creates an isolated user-defined network per job, so
# each job gets its own embedded DNS. Concurrent jobs can no longer collide on
# service container names (e.g. two jobs both exposing a host named `redis`).
"network" => ""
},
"cache" => {
"enabled" => true,
"host" => "172.20.0.1" # Gateway of the gitea-actions network, reachable from job containers
# Empty: auto-detect the host address reachable from job containers. The runner
# is a host binary (not containerized), so a per-job network resolves this to a
# reachable gateway. Set explicitly only if detection picks a wrong interface.
"host" => ""
# Port is set per-runner (cache_base_port + index) in the runner recipe
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ maintainer_email 'ops@kosmos.org'
license 'MIT'
description 'Installs/configures Gitea'
long_description 'Installs/configures Gitea'
version '0.3.4'
version '0.3.5'
chef_version '>= 14.0'
depends "firewall"
@@ -38,9 +38,12 @@ directory "#{working_directory}/runners" do
mode "0700"
end
execute "create_gitea_actions_network" do
command "docker network create --subnet 172.20.0.0/16 gitea-actions"
not_if "docker network inspect gitea-actions"
# One-time cleanup of the previously shared bridge network. Skipped while jobs are
# still attached; the next converge removes it once the runner is idle.
execute "remove_gitea_actions_network" do
command "docker network rm gitea-actions"
only_if "docker network inspect gitea-actions"
not_if "docker network inspect -f '{{len .Containers}}' gitea-actions | grep -qv '^0$'"
end
runners.each_with_index do |runner, index|
@@ -59,7 +62,9 @@ runners.each_with_index do |runner, index|
command :allow
port cache_port
protocol :tcp
source "172.20.0.0/16"
# Job containers now run on auto-created per-job networks, which Docker
# allocates from its default address pool (172.16.0.0/12).
source "172.16.0.0/12"
end
template "#{runner_dir}/config.yaml" do