# App installs fail intermittently in `umbrel-dev`: DNS resolution breaks after container/app lifecycle events
Summary
In a local umbrel-dev (docker-based dev environment) instance, Docker
image pulls inside the container intermittently fail with DNS timeouts,
which in turn causes app installs to silently stall (stuck at a low
percentage, then reverts to "Install") with no container ever created.
This is not a one-time setup issue — it is reproducible on demand by following a specific sequence involving uninstalling and reinstalling a community app.
Related, already-reported issues
This appears to be the same underlying category of problem as two existing reports on this repo:
- https://github.com/getumbrel/umbrel/issues/1785 — reports that an app install can get stuck, and specifically that this "also occurs when you try to install an already installed app," with the suggested workaround being to remove all Umbrel containers and reinstall.
- https://github.com/getumbrel/umbrel/issues/1853 — reports installs
silently failing from the Umbrel Store, root-caused there to Docker
image pulls failing underneath the UI, discoverable by running
docker pullmanually and seeing the real error the UI doesn't surface.
Both match the symptoms below closely, but neither pins down the DNS/
UDP:53-specific root cause, or the exact uninstall→reinstall trigger that
makes it reproducible on demand. This report adds that concrete,
minimal reproduction inside umbrel-dev specifically, plus what was and
wasn't effective as a fix.
Environment
umbrel-dev(docker-container-based dev instance, pergetumbrel/umbrel's own dev tooling)- Host: Ubuntu, Docker Engine (host), nested Docker daemon inside the
umbrel-devcontainer itself umbrel-devcontainer created via the standardnpm run devflow
Steps to reproduce
- Start
umbrel-devfresh (npm run dev start, ordocker start umbrel-devon an existing instance). - Confirm baseline:
docker exec umbrel-dev docker pull hello-worldsucceeds. - Install any community app (e.g. Bitcoin Node) through the dashboard — this succeeds.
- Uninstall that same app through the dashboard.
- Attempt to reinstall it (or install a different app) immediately after.
- Observe: the install progress bar advances to some low percentage (varies: 1%, 4%, 30% observed across different attempts) and then silently reverts to the "Install" button. No error is shown in the UI.
- Confirm no container was created:
docker exec umbrel-dev docker ps -a | grep <app-name>returns nothing. - Confirm the underlying cause:
docker exec umbrel-dev docker pull hello-worldnow fails with:Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on <dns-server>:53: read udp ...: i/o timeout
What we confirmed about the root cause
- Raw network connectivity from the container is fine
(
ping 8.8.8.8succeeds). - Plain system-level DNS resolution works
(
getent hosts registry-1.docker.ioreturns valid IPv6 addresses). - Those IPv6 addresses are unreachable from the container specifically
(
curl -6 https://registry-1.docker.io/v2/→ "Network is unreachable"), while IPv4 (curl -4) connects immediately. - DNS-over-HTTPS (port 443) works reliably; plain UDP:53 queries (what Docker's own resolver uses) consistently time out, even against known-good public resolvers (8.8.8.8, 1.1.1.1).
- This points to UDP:53 traffic specifically being dropped somewhere
between the nested Docker daemon (inside
umbrel-dev) and the network, rather than a broader connectivity or firewall issue.
What we tried that did NOT resolve it
- Restarting the Docker daemon inside the container
(
systemctl restart docker) after changing/etc/docker/daemon.jsonto set explicit DNS servers (8.8.8.8,1.1.1.1) — the resultingdocker pullstill timed out on the same public resolvers. - Disabling IPv6 at the kernel level inside the container
(
sysctl -w net.ipv6.conf.all.disable_ipv6=1) — did not change the outcome; the DNS query itself still timed out even over IPv4 after this change. - A full
docker restart umbrel-dev(not a volume wipe) — this resolves the DNS issue temporarily (confirmed via a freshdocker pull hello-worldsucceeding right after restart), but the same failure reliably returns after the uninstall/reinstall sequence above is repeated. So a plain container restart is not a fix, only a temporary reset of whatever state gets corrupted by the uninstall/reinstall cycle.
What did work (destructive, last resort)
- A full, clean reset — stopping and removing the container, then
removing the underlying data volume entirely
(
docker volume rm umbrel-dev) — followed by a freshnpm run dev start, produced a working instance wheredocker pullsucceeded immediately and the first app install completed successfully. - However, this is not a real fix: it discards all existing app data and state, and — critically — the same failure reproduces again as soon as the uninstall → reinstall sequence (steps 4–5 above) is repeated on this fresh instance. So the underlying trigger is not something present only in old/corrupted state; it is actively reintroduced by the normal uninstall/reinstall app lifecycle itself.
Practical, non-destructive workaround (temporary, must be reapplied)
Manually resolve the specific hostnames Docker needs via DNS-over-HTTPS
and hardcode them into the container's /etc/hosts:
docker exec umbrel-dev sh -c "echo 'nameserver 8.8.8.8' > /etc/resolv.conf"
docker exec umbrel-dev sh -c "curl -s --doh-url https://1.1.1.1/dns-query \
'https://cloudflare-dns.com/dns-query?name=registry-1.docker.io&type=A' \
-H 'accept: application/dns-json'"
# repeat for auth.docker.io and production.cloudfront.docker.com, then:
docker exec umbrel-dev sh -c "echo '<ip> registry-1.docker.io' >> /etc/hosts"This restores docker pull immediately, but does not survive a
container restart (/etc/resolv.conf and /etc/hosts both reset to
defaults), and the CDN host's IP in particular has a very short TTL
(30-60s) and needs re-resolving frequently.
Open question
What specifically changes, during an app uninstall/reinstall cycle, that breaks UDP:53 DNS resolution for the nested Docker daemon each time — given that a plain restart of the same container (without that cycle) does not by itself reintroduce the problem?
Source: getumbrel/umbrel