Containerizing your DNS is a special kind of scary
Most services degrade when they go down. The media server is unavailable and someone watches something else. A web server is unreachable and you get an error page.
DNS does not degrade. When the resolver stops answering, every device on the network simultaneously loses the ability to reach anything by name, and none of them tell you that DNS is the problem. They tell you the internet is broken.
That is the context for moving Pi-hole from a native install into a container, and it changed how I approached the whole thing.
The window
The cutover is: stop the native service, start the container. Between those two events, nothing on the network can resolve a name. Realistically ten to thirty seconds.
Thirty seconds is nothing, right up until you enumerate what is actually happening during it:
- Every device with that host as its only resolver fails every lookup for the duration
- Anything mid-request times out rather than retrying cleanly
- If the resolver also runs DHCP, that is unavailable too
Existing DHCP leases keep devices online through it, so the practical risk there is narrow: a device whose lease happens to need renewing inside that window. Narrow is not zero, and the failure mode is a device dropping off the network entirely rather than just being slow.
None of that is a reason not to do it. It is a reason to do it deliberately, at a time you choose, rather than at four in the afternoon because you happened to be at the keyboard.
Secondary DNS will not save you
The instinct is to point clients at a public resolver as a secondary and let it cover the gap.
It does not work the way people expect, and this is worth knowing regardless of containers.
A secondary resolver is failover for a resolver that is not answering. It is not a fallback for one that answers in a way you did not want. If your primary is up and returns NXDOMAIN, that is a valid answer, the client accepts it, and the secondary is never consulted.
Which also means: during the actual cutover, when the primary is genuinely down, a secondary does help. But you cannot use "there is a secondary configured" as general reassurance, because for every other failure mode it is doing nothing. And if you rely on the resolver for local name resolution, a secondary that does not know your local records will confidently answer for names it should not.
The port 80 thing, and why it was safe
Separately from the container work, I needed ports 80 and 443 on that host to put a reverse proxy in front of some other services. Pi-hole's admin interface was sitting on them.
Moving the admin UI to different ports is a one-line config change. Whether it is safe depends on a detail that has nothing to do with the admin interface.
Pi-hole can respond to a blocked domain in more than one way. If it is configured to serve a block page, it answers the DNS query with its own address, the client then makes an HTTP request to port 80 expecting a page explaining the block, and Pi-hole serves one. Under that setup, vacating port 80 changes what every blocked request looks like on every device on the network. Instead of a block page you get a connection error, which looks like something broken rather than something working as configured.
Mine is set to null blocking, where blocked domains resolve to an unroutable address and no HTTP request follows. Nothing was ever expecting a page on port 80, so moving the admin interface off it changed nothing for clients.
Same config change, two very different blast radii, and which one you are in is determined by a setting in a different part of the product. Worth checking before assuming a port move is cosmetic.
What made it survivable
The same pattern I use for any cutover on a service people depend on:
- The native install stays fully intact. The container gets a copy of the config directory, never the original.
- Host networking, so the container answers on the same address and port. No client reconfiguration, and source IPs stay intact so per-client query logs still work.
- The container keeps the capability it needs for DHCP, in case that is in use.
- Rollback written out before starting: stop the container, re-enable the native service.
That last one is the difference between a fifteen second outage and an hour of troubleshooting with no working DNS to look anything up with. Which is its own trap worth naming: when DNS is the thing you broke, you have also broken your ability to search for how to fix it.
Have the rollback on screen before you run the cutover. Not in a browser tab you will need working DNS to reload.