feat: propagate proxy variables to jobs, services and builds (#1112)

Set `http_proxy`, `https_proxy` and `no_proxy` in the runner's environment and everything the runner controls uses them.

Go already read them for the runner's own requests. This adds jobs, in lower and upper case, service containers, and Dockerfile action builds.

Some hosts are added to `no_proxy` for jobs so they stay direct: the cache server, loopback, the job's service containers, and a `tcp://` Docker daemon. Without the last one the Docker client sends its API calls to the proxy and docker-in-docker breaks. Gitea is not added.

Images are pulled by the Docker daemon, which has its own proxy setting. In the `dind` images it reads these same variables. The runner warns at startup if it has a proxy and the daemon does not.

Fixes https://gitea.com/gitea/runner/issues/1118, originally reported as https://gitea.com/gitea/runner/issues/708.

---------

Co-authored-by: silverwind <2021+silverwind@noreply.gitea.com>
Co-authored-by: silverwind <me@silverwind.io>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1112
Reviewed-by: silverwind <2021+silverwind@noreply.gitea.com>
Co-authored-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni
2026-07-30 08:15:48 +00:00
committed by silverwind
parent 3f7fd16ea1
commit 41c72216bf
15 changed files with 532 additions and 4 deletions

View File

@@ -435,7 +435,9 @@ func (rc *RunContext) startJobContainer() common.Executor {
continue
}
// interpolate env
interpolatedEnvs := make(map[string]string, len(spec.Env))
interpolatedEnvs := make(map[string]string, len(spec.Env)+len(rc.Config.ProxyEnv))
// a service reaches the internet the way the job does; its own env still wins
maps0.Copy(interpolatedEnvs, rc.Config.ProxyEnv)
for k, v := range spec.Env {
interpolatedEnvs[k] = rc.ExprEval.Interpolate(ctx, v)
}
@@ -969,6 +971,20 @@ func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
return true, nil
}
// proxyBuildArgs returns the job's proxy variables as docker build args. The docker CLI
// pre-populates these from its own client configuration, but act builds through the API,
// so without them a Dockerfile action's RUN steps have no network behind a proxy.
func (rc *RunContext) proxyBuildArgs() map[string]*string {
if len(rc.Config.ProxyEnv) == 0 {
return nil
}
args := make(map[string]*string, len(rc.Config.ProxyEnv))
for name, value := range rc.Config.ProxyEnv {
args[name] = &value
}
return args
}
func mergeMaps(maps ...map[string]string) map[string]string {
rtnMap := make(map[string]string)
for _, m := range maps {