Virtualization

Docker containers lose DNS resolution after laptop resume on Ubuntu 22.04 due to systemd-resolved stub resolver change

Environment

Environment

Ubuntu 22.04 desktop (kernel 5.15), Docker Engine 20.10.17, containers use default bridge network and rely on host's /etc/resolv.conf provided by systemd-resolved (127.0.0.53). Laptop uses NetworkManager with two interfaces: Wi‑Fi and VPN tun0 (WireGuard).

Symptoms

Symptoms

After resuming from suspend, running containers cannot resolve DNS names (e.g., apt update inside container fails resolving registry-1.docker.io); host DNS resolution works. Restarting Docker daemon temporarily restores resolution for a short period; then after next suspend it fails again.

Observations

Observations

Inside container: resolv.conf contains 127.0.0.53. host's /etc/resolv.conf is a symlink to /run/systemd/resolve/stub-resolv.conf. systemd-resolved status shows 'DNS Servers:' correct values but systemd-resolved.log shows messages 'Watchdog: interface tun0 disappeared' and 'Registered new stub listener on 127.0.0.53:53' after resume. strace of containerized process shows connect to 127.0.0.53:53 returns ECONNREFUSED periodically. Restarting Docker recreates containers and their /etc/resolv.conf entries then resolution works until next suspend. Disabling and re-enabling network interface on host doesn't affect containers' resolv failure; restarting systemd-resolved fixes host+containers.

Already attempted

Already attempted

Restarted systemd-resolved (systemctl restart systemd-resolved) — fixed host and containers until next suspend. Restarted docker.service — temporary fix. Recreated containers with --network host — resolves DNS reliably. Replaced /etc/resolv.conf inside container to point at public DNS (8.8.8.8) — works but undesirable due to split-DNS for VPN.

Question

Question

How can I make Docker containers continue to resolve host-provided DNS (systemd-resolved stub) reliably across suspend/resume without restarting daemon or the containers? Is there a safe, persistent configuration change to prevent the stub listener from becoming unusable for containers after resume?

COMMUNITY RESPONSES

Verified community troubleshooting

0 replies

No answers yet..

Showing 0 of 0 community responses
AI DIAGNOSTICS

Incident analysis

Updated 1w ago• Trouble ID

Most likely causes

systemd-resolved rebinds its stub listener during resume, invalidating connections used by containers that reference 127.0.0.53. 95%
NetworkManager/VPN reconfiguration on resume causes systemd-resolved to cycle listeners and transiently refuse connections used by containers. 85%
Docker created container /etc/resolv.conf entries before resume and they reference a transient listener socket that later becomes unreachable. 40%

Summary

Containers rely on the host's stub resolver at 127.0.0.53. After suspend/resume, systemd-resolved appears to rebind or recreate its stub listener; the ephemeral listener state breaks the socket that containers previously used (their /etc/resolv.conf still points to the prior listener, which now refuses connections). Restarting systemd-resolved restores listener; restarting Docker updates container resolv.conf indirectly. Root causes include systemd-resolved re-registering listeners on resume, network interface reconfiguration (VPN) that triggers listener rebinds, and containers caching or keeping old socket endpoints. The safe solution is to avoid containers depending on host-local stub listener socket address, or ensure resolv.conf in containers points to a stable resolver.

Suggested Fixes

Diagnostic step 1
Avoid pointing containers at the host stub resolver. Configure Docker daemon to use stable DNS servers for containers (edit /etc/docker/daemon.json and add "dns": ["127.0.0.1"] is not sufficient here; instead provide one or more resolvers reachable from containers, e.g., internal resolver IP on LAN). After changing daemon.json, restart docker.service.
Diagnostic step 2
As a VPN/split-DNS requirement: run a small DNS forwarder (dnsmasq or unbound) bound to a stable host IP (not 127.0.0.53) reachable by containers; configure Docker daemon 'dns' to that IP so container resolv.conf uses a stable endpoint.
Diagnostic step 3
If you must continue using systemd-resolved, add a resume hook to restart systemd-resolved (sudo systemctl restart systemd-resolved) or to reconfigure Docker containers' /etc/resolv.conf after resume (create a systemd unit in /etc/systemd/system that runs after sleep.target to run 'systemctl restart docker' or execute a script to update container resolv.conf). This is a workaround; restarting Docker will briefly disrupt containers.

Continue troubleshooting

Matched from the title, description and tags