fix(ci): build with the host network until the runner resolves DNS #23

Merged
piscis merged 3 commits from piscis/forgejo-image-ci into main 2026-09-30 14:51:40 +00:00
Owner

Refs #22. Follow-up to #20 (#6): ci has been red on main since #20 merged, because the build's RUN steps can't resolve DNS on the runner.

Summary

 # Makefile
+BUILD_NETWORK ?=            # empty: the daemon's default network
 build:
-  docker buildx build --platform "$$p" \
+  docker buildx build --platform "$$p" $(if $(BUILD_NETWORK),--network "$(BUILD_NETWORK)") \

 # .forgejo/workflows/ci.yml
   - uses: actions/checkout@v4
+    with:
+      persist-credentials: false        # nothing in the job pushes to git
-  - run: docker run --rm --privileged tonistiigi/binfmt --install arm64
+  - run: docker run --rm --privileged tonistiigi/binfmt:qemu-v10.2.3-68@sha256:400a48… --install arm64
-  - run: make build IMAGE="$IMAGE"
+  - run: make build IMAGE="$IMAGE" BUILD_NETWORK=host    # until #22 is fixed

Why the builds fail: the dind daemon has only its default bridge. Containers on that bridge, including BuildKit RUN steps, fall back to 8.8.8.8/8.8.4.4, and DNS to those times out from the runner. With --network host, RUN steps use the dind container's own resolver (127.0.0.11), which works. The real fix is on the runner; #22 has the details from a probe run (18).

A local make build doesn't change: BUILD_NETWORK is empty unless set.

How it was verified

Case Run Result
Before: uncached build, two concurrent dispatches on f6e2437 14, 15 red: apk add git → DNS: transient error
Before: uncached build on main, run alone 16, 17 red, same error
Probe: DNS on the dind daemon, bridge vs host network 18 bridge: nslookup times out; --network host and buildx build --network host resolve
After: two concurrent dispatches, cold cache 19, 20 green; apk add and git clone ran, PASS: 156 tools listed on amd64 and arm64
After: this PR's head 4bb73ae, PR run plus two dispatches concurrently 21, 22, 23 all three green on amd64 and arm64
  • Checkout token: before, the token stayed in .git/config until the post-job step removed it. Now actions/checkout logs "Removing auth" right after the fetch, before any build step.
  • Nothing pushed: there's still no docker login and no --push, and the build only uses --load. GET /api/v1/packages/vicoli-oss?type=container still returns [].
  • /code-review against b8d583d (all of #20 plus this PR):
    • Fixed here: pin tonistiigi/binfmt by digest, since it runs --privileged on the shared daemon for every PR; and the Makefile comment now says why CI sets BUILD_NETWORK.
    • Not fixed here: a cached clone layer on the shared daemon can hide an Upstream tag that moves without a Pin change; step names hard-code amd64/arm64; build cache isn't pruned.

Merge Danger

Door: two-way

Revert the commit, or once #22 is fixed drop BUILD_NETWORK=host from ci.yml.

Blast Radius: CI

Only the ci workflow's build step changes. RUN steps share the dind container's network namespace, so they can reach anything listening there, including the daemon's own port. The job already has full daemon access, so for this repo's own PRs that adds little, but the workaround shouldn't become permanent (#22).

Refs #22. Follow-up to #20 (#6): `ci` has been red on main since #20 merged, because the build's `RUN` steps can't resolve DNS on the runner. ## Summary ```diff # Makefile +BUILD_NETWORK ?= # empty: the daemon's default network build: - docker buildx build --platform "$$p" \ + docker buildx build --platform "$$p" $(if $(BUILD_NETWORK),--network "$(BUILD_NETWORK)") \ # .forgejo/workflows/ci.yml - uses: actions/checkout@v4 + with: + persist-credentials: false # nothing in the job pushes to git - - run: docker run --rm --privileged tonistiigi/binfmt --install arm64 + - run: docker run --rm --privileged tonistiigi/binfmt:qemu-v10.2.3-68@sha256:400a48… --install arm64 - - run: make build IMAGE="$IMAGE" + - run: make build IMAGE="$IMAGE" BUILD_NETWORK=host # until #22 is fixed ``` Why the builds fail: the dind daemon has only its default bridge. Containers on that bridge, including BuildKit `RUN` steps, fall back to `8.8.8.8`/`8.8.4.4`, and DNS to those times out from the runner. With `--network host`, `RUN` steps use the dind container's own resolver (`127.0.0.11`), which works. The real fix is on the runner; #22 has the details from a probe run ([18](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/18)). A local `make build` doesn't change: `BUILD_NETWORK` is empty unless set. ## How it was verified | Case | Run | Result | |---|---|---| | Before: uncached build, two concurrent dispatches on `f6e2437` | [14](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/14), [15](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/15) | **red**: `apk add git` → `DNS: transient error` | | Before: uncached build on main, run alone | [16](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/16), [17](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/17) | **red**, same error | | Probe: DNS on the dind daemon, bridge vs host network | [18](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/18) | bridge: `nslookup` times out; `--network host` and `buildx build --network host` resolve | | After: two concurrent dispatches, cold cache | [19](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/19), [20](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/20) | green; `apk add` and `git clone` ran, `PASS: 156 tools listed` on amd64 and arm64 | | After: this PR's head `4bb73ae`, PR run plus two dispatches concurrently | [21](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/21), [22](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/22), [23](https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp/actions/runs/23) | all three green on amd64 and arm64 | - **Checkout token:** before, the token stayed in `.git/config` until the post-job step removed it. Now `actions/checkout` logs "Removing auth" right after the fetch, before any build step. - **Nothing pushed:** there's still no `docker login` and no `--push`, and the build only uses `--load`. `GET /api/v1/packages/vicoli-oss?type=container` still returns `[]`. - **`/code-review`** against `b8d583d` (all of #20 plus this PR): - Fixed here: pin `tonistiigi/binfmt` by digest, since it runs `--privileged` on the shared daemon for every PR; and the Makefile comment now says why CI sets `BUILD_NETWORK`. - Not fixed here: a cached clone layer on the shared daemon can hide an Upstream tag that moves without a Pin change; step names hard-code amd64/arm64; build cache isn't pruned. ## Merge Danger **Door:** two-way Revert the commit, or once #22 is fixed drop `BUILD_NETWORK=host` from `ci.yml`. **Blast Radius:** CI Only the `ci` workflow's build step changes. `RUN` steps share the dind container's network namespace, so they can reach anything listening there, including the daemon's own port. The job already has full daemon access, so for this repo's own PRs that adds little, but the workaround shouldn't become permanent (#22).
On the dind daemon's default bridge, RUN steps fall back to Google DNS,
which doesn't answer from the runner, so every uncached build failed in
apk add. Also stop persisting the checkout token: nothing here pushes.
ci: pin tonistiigi/binfmt by digest, say in the Makefile why CI sets BUILD_NETWORK
All checks were successful
ci / build (pull_request) Successful in 10s
4bb73ae989
Both from /code-review: binfmt runs --privileged on the shared daemon for
every PR, and BUILD_NETWORK's comment didn't say it's a workaround for #22.
piscis merged commit d23096dae7 into main 2026-09-30 14:51:40 +00:00
piscis deleted branch piscis/forgejo-image-ci 2026-09-30 14:51:40 +00:00
Sign in to join this conversation.
No description provided.