Dns inside the docker is not updating when network=host

I am using rpi5 as host and Network Manager for network management. And the docker info as below Client: Docker Engine - Community
Version: 27.3.1
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.17.1
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.29.7
Path: /usr/libexec/docker/cli-plugins/docker-compose

Server:
Containers: 3
Running: 3
Paused: 0
Stopped: 0
Images: 16
Server Version: 27.3.1
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7f7fdf5fed64eb6a7caf99b3e12efcf9d60e311c
runc version: v1.1.14-0-g2c9f560
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.6.62+rpt-rpi-2712
Operating System: Debian GNU/Linux 12 (bookworm)
OSType: linux
Architecture: aarch64
CPUs: 4
Total Memory: 3.946GiB
Name: raspberrypi
ID: 2395f530-5901-4bf8-a24d-bf58fd633257
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false

WARNING: No memory limit support
WARNING: No swap limit support
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

The network_mode is set as host network_mode: host and also mounting the
volumes:
- /etc/resolv.conf:/etc/resolv.conf:ro

ISSUE:

The updated dns is not reflecting inside the docker hence name resolution failed. Docker only accepting the dns while it is starting

What do you mean? DNS entries usually have a TTL (time-to-live), so when entries are changed upstream, it might take a while for all resolvers to re-fetch the latest data, potentially even some hours.

Files are not mounted by path. Their inode is looked up and used to mount the file by inode into the container. If resolv.conf changes, it’s inode changes. Of course docker will not be able to see the modified file.

okay how to resolve this.
I have a doubt. doesn’t the “network_mode = host” handle this?

I understand the problem you try to solve, but I am astonished that it’s actually a problem. On none of my docker hosts the /etc/resolv.conf changes on a regular basis. I shared in my previous post why the /etc/resolv.conf has the content from the point in time when the container was created.

If you feel it’s a bug, please raise an issue in docker’s upstream project Moby.

The way docker works right now, the solution must be established outside of docker. For instance, you could try if using the systemd-resolved dns stub resolver helps, as the entry in /etc/resolv.conf would point to the fixed dns stub resolvers ip, the upstream dns servers would be configured in systemd-resolved then.

Thanks for the explanation, that clarifies Docker’s behavior.

I understand now that Docker copies /etc/resolv.conf only at container creation time and does not track subsequent DNS changes, and that this is currently by design.

In my environment (Raspberry Pi / NetworkManager), the host DNS configuration changes dynamically (for example, on network reconnects), which causes the container to end up with stale DNS entries even though DNS works correctly on the host. That’s why this becomes an operational issue for us.

Based on your suggestion, I’ll try using systemd-resolved with the DNS stub resolver so that /etc/resolv.conf points to a stable local resolver and upstream DNS changes are handled outside Docker.

Please let me know if you see any drawbacks to this approach in production, or if you’d recommend an alternative host-level solution.

Just to be sure, with “stale DNS entries” you mean stale configuration for the nameservers in /etc/resolv.conf.
You could try dnsmasq instead of the systemd-resolved stub resolver. I would suggest trying both, just not at the same time.

Though, f you meant caching of the resolved dns names, then @bluepuma77 gave an answer about it. This problem is not solved dnsmasq or systemd-resolved. This problem needs to be solved in the upstream dns server by using appropriate TTLs.

Thanks for the explanation. To clarify my observation: on the host, DNS changes dynamically (e.g., due to network changes), and the host continues to resolve names and reach the internet correctly. However, Docker containers created before the change appear to retain stale DNS behaviour and fail to resolve names.
This makes me wonder whether /etc/resolv.conf is the only factor causing this resolver issue, or whether Docker’s DNS configuration is inherently static after container creation. Even without explicitly bind-mounting /etc/resolv.conf, I would expect containers—especially when using network_mode: host—to follow the host’s DNS behaviour after a network change, but that does not seem to be happening in my case.

So my questions are:

  • Does Docker effectively “freeze” DNS configuration at container creation time and remain unaware of subsequent host network/DNS changes?
  • Is /etc/resolv.conf the only evidence/source Docker uses for name resolution, or are there other resolver states that can remain stale?
  • In a host-networked container, is it expected that DNS resolution still requires container recreation after host DNS changes?

I’m trying to understand whether this behavior is by design or if there is a recommended way to make containers reliably track host DNS changes.

As I already wrote files are mounted using their inode (~their logical position in the filesystem), which changes if a file changes. This affects all files, not just /etc/resolv.conf. Though, If you would bind a host folder to a container folder,updates to files inside this folder and/or arbitrary subfolders would be visible on both sides - after all both point to the same inode.

it also uses /etc/hosts, which people usually use if they need domain resolution, but have no control over the upstream dns resolvers, or just want to introduce local names.

Yes. I hopped this would have been clear by now, unless you use a stub resolver or something like dnsmasq.

I am pretty sure this is a limitation how the mount namespaces work in Linux for single file mount. It is not a limitation introduced by docker. Note: in case of /etc/resolv.conf and /etc/hosts and /etc/hostname are copied into the container metadata folder, which is then bind mounted into the actual container.

This is my last response to the topic, as I feel that we spin in circles.