--- date: 2026-10-30 branch: fix/renovate-first-run title: Renovate never started because its action needs a Docker daemon jobs here do not get; it now runs as the job container --- ## What changed **`.gitea/workflows/renovate.yaml`**: the job no longer uses `renovatebot/github-action`. The pinned Renovate image (`ghcr.io/renovatebot/renovate:44.167.0`, the same version the action was pinned to) is now the job's `container:`. A `run:` step calls `renovate-entrypoint.sh renovate` inside it. `actions/checkout` is gone, because Renovate clones the repo itself. `GITHUB_COM_TOKEN` is wired from a new **optional** secret, `RENOVATE_GITHUB_COM_TOKEN`. The step unsets it, and `RENOVATE_DRY_RUN`, when they evaluate to the empty string. The preflight also prints `renovate --version`, which proves the step ran inside the pinned image. **`renovate.json5`**: one comment now names `container.image` as the version pin, in place of `renovate-version`. The config itself is unchanged. ### Why: the root cause Every run of the action died before Renovate started. That includes the operator's dispatch, run 343 (task 555, 2026-10-30 06:14 UTC), and the 11 scheduled runs before it (312–322). From run 343's log: RENOVATE_TOKEN is present (value not printed). [command]/usr/bin/docker run --env LOG_LEVEL ... --env RENOVATE_TOKEN=*** --env RENOVATE_CONFIG_FILE=/github-action/renovate.json5 ... failed to connect to the docker API at unix:///var/run/docker.sock; check if the path is correct and if the daemon is running: dial unix /var/run/docker.sock: connect: no such file or directory Error: The process '/usr/bin/docker' failed with exit code 1 The action is only a wrapper around `docker run`. On this runner a job deliberately gets no Docker daemon (`decisions/2026-10-29-image-pipeline.md`): act_runner maps `docker_host` to `-` when `DOCKER_HOST` is `tcp://`, and the DinD daemon is privileged. So this was a platform-compatibility failure. The run never reached authentication, token scope, config or the network. **The re-minted token is not implicated, and nothing in this log can say whether its scopes are right.** A job `container:` needs no daemon. act creates it through the runner's DinD the same way it creates the default `ubuntu-latest` image, then `exec`s each step inside it. I checked this against gitea/act v0.261.2: - The job container's entrypoint is `/bin/sleep` (`run_context.go`). The Renovate image has `/usr/bin/sleep`. - The step command files are written `0o666` (`step.go`), so the image's uid 12021 can write `$GITHUB_STEP_SUMMARY`. - `HOME` comes from the image env. ## What I verified - **The root cause.** I read all of run 343's job log (162 lines, job 0; job 1 is 404). It has one error, quoted above, and no Renovate output at all. Runs 312–322 are all `failure` from the `schedule` event. - **The config validates against the pinned tag.** `podman run ... ghcr.io/renovatebot/renovate:44.167.0 renovate-config-validator /tmp/renovate.json5` printed `Config validated successfully`. It also printed the known migration diff for the top-level `docker` block. - **A dry run with the fix extracts and looks up dependencies.** This was a local reproduction. I made a clean snapshot of this branch's tracked files. I ran it in a podman container of the pinned image with entrypoint `/bin/sleep`, as the image's own uid 12021 with `HOME=/home/ubuntu`. Inside it I `exec`ed the workflow step's `run:` body, extracted verbatim from the YAML, with: - `RENOVATE_PLATFORM=local`, `RENOVATE_DRY_RUN=full` and `GITHUB_COM_TOKEN=` (empty, to exercise the unset); - a docker host rule for `gitea.home.keithjackson.dev` using the `gitea-admin` credential from `~/.git-credentials`, passed through env and never printed. The run exited 0 and logged `Dependency extraction complete`: - flux 15 deps / 13 files - github-actions 24 / 4 - kubernetes 131 / 67 - kustomize 2 / 2 - regex (both custom managers) 7 / 6 - **total 179 deps / 92 files** It found **42 updates**: 29 kubernetes, 6 flux, 2 kustomize, 1 github-actions and 4 regex `digest`. 7 of them are `major`. - **The `# renovate-digest:` lookups against the Gitea registry succeed.** All three `/v2/token?scope=repository:home-network/:pull` requests succeeded, and so did `HEAD /v2/home-network//manifests/main`. They proposed `digest` updates for `conformance/versions.env`, `infra/agent/versions.env`, `platform/pm-agent/configmap.yaml` and `platform/pm-agent/deployment.yaml`, all of which carry the zero placeholder digest today. The `kubernetes` manager's copies of those images report `disabled`, which is the intended effect of the packageRule. - **The new pin is still maintained by Renovate.** The github-actions manager extracts `ghcr.io/renovatebot/renovate:44.167.0` from `renovate.yaml` as depType `container`, and proposes 44.198.0. - **The `regex` vs `custom.regex` question from #73/#77 is closed.** Both custom managers produced dependencies. - **Missing GitHub token.** The local run logged `GitHub token is required for some dependencies`. That accounts for 17 deps skipped with `github-token-required`, which is why `RENOVATE_GITHUB_COM_TOKEN` is offered as an optional secret. ## What I did NOT verify - **The workflow on the real runner. UNVERIFIED.** My reproduction ran with podman, not act_runner + DinD, and used `--platform=local`. The act behaviour (sleep entrypoint, `exec` as the image user, 0666 command files) comes from reading the gitea/act v0.261.2 source, not from a run. The first real evidence will be a `workflow_dispatch` after merge. - **The Gitea platform path and `RENOVATE_TOKEN`'s scopes. UNVERIFIED.** I have no access token, only the `gitea-admin` password, which Renovate's Gitea platform cannot use. So these were not exercised: platform init (`GET /user`, which needs `read:user`), repo clone, and the registry lookups using the **token** with `read:package` rather than a password. - **Behaviour inside the schedule window.** A dispatch outside 03:00–06:00 America/New_York (07:00–10:00 UTC during EDT) will extract and look up, but will log "not within schedule" instead of `DRY-RUN: Would create ...` lines. I did not change this. - **Renovate as uid 12021 doing artifact updates** (for example helm lockfiles) on a real, non-dry run. `--dry-run=full` does not run the tools. - **The self-bump.** Renovate will propose `ghcr.io/renovatebot/renovate` 44.167.0 → 44.198.0 as a minor, which the default rule auto-merges. `.gitea/**` is a sensitive path, so it will in fact wait for an administrator override. Nothing re-runs `renovate-config-validator` on that bump, and no gate check runs the validator. - **No alert for "Renovate red every day".** That gap is still open. This failure ran for 12 days without anyone noticing. - **Sensitive path.** `.gitea/**` is in `infra/gitea/approval-policy.json`, so CI's `approval-policy` stage will block until the operator posts `/approve-override` as a PR review.