Submit an issue View all issues Source
MIR-1695

Builds resolve DNS against public 8.8.8.8 instead of the host resolver

In Progress public
evan evan Opened Aug 30, 2026 Updated Aug 30, 2026

Summary

Container image builds silently resolve DNS against public servers (8.8.8.8 / 8.8.4.4) instead of the host's configured resolver. On a host that uses a systemd-resolved stub — nameserver 127.0.0.53 in /etc/resolv.conf — with an internal-only or egress-filtered upstream, builds can't resolve names at all. This was reported by a user whose build environment couldn't do DNS.

Root cause

Build RUN steps run in the host network namespace: with no CNI config present, buildkit's "auto" network mode falls back to host networking (it logs using host network as the default). But buildkit generates each build's resolv.conf as if it were sandboxed. The RUN step's NetMode is UNSET, not HOST, so buildkit's GetResolvConf:

  1. strips every loopback nameserver — the whole 127.0.0.0/8 range, so 127.0.0.53 included — and,
  2. finding nothing left, substitutes public DNS (8.8.8.8 / 8.8.4.4).

It also can't recover the host's real upstream servers, because /run/systemd/resolve/resolv.conf (which holds them behind the stub) isn't mounted into the buildkitd container — only the host's /etc/resolv.conf is, via oci.WithHostResolvconf.

The result: even though the build sits in the very netns where 127.0.0.53 would resolve, buildkit throws it away and hardcodes public DNS — exactly the "breaks builds on hosts with an internal resolver" case the earlier MIR-1643 note was trying to avoid.

Fix

Point builds at miren's own bridge DNS server. Miren already runs a resolver on the bridge gateway (e.g. 10.8.13.1:53) for runtime sandboxes; it forwards to the host's real upstream and answers *.app.miren. We add a [dns] section to the generated buildkitd.toml naming that address, wired in from the network boot node's router address. The bridge gateway is a local interface in the host netns, so it's reachable from build steps, and buildkit keeps it — it isn't a loopback address, so the loopback filter leaves it alone.

Verification

Rebuilt and ran a real Dockerfile build in the dev environment:

  • Before: RUN cat /etc/resolv.conf showed nameserver 8.8.8.8.
  • After: nameserver 10.8.13.1, and nslookup example.com resolves through it successfully (exit=0).