Skip to content

Conversation

mmssantos
Copy link

Took a quick shot at implementing an automatic mechanism to programmatically grab the local dns resolver ip address from /etc/resolv.conf and update the nginx.conf file resolver directive with it, removing the hardcoded configuration.
Tested on Kubernetes and on a local docker instance and working fine.
Probably needs a bit more testing and script sanitization.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a dynamic DNS resolver configuration system for nginx by automatically extracting the local DNS resolver IP address from /etc/resolv.conf and updating the nginx configuration template, replacing the hardcoded 127.0.0.11 resolver.

  • Adds a shell script to dynamically capture DNS resolver addresses from /etc/resolv.conf
  • Converts the static nginx configuration to a template-based approach using environment variable substitution
  • Updates the Docker build process to execute the DNS resolver detection script during container startup

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
Dockerfile Updates build to use nginx.conf.template and adds execution permissions for the new DNS resolver script
.docker/scripts/90-awk-nginx-conf-with-resolv-conf.sh New script that extracts DNS resolvers from /etc/resolv.conf and generates nginx.conf from template
.docker/nginx.conf.template Converts hardcoded resolver to use NGX_DNS_RESOLVER environment variable placeholder

@Nerivec
Copy link
Owner

Nerivec commented Sep 18, 2025

I gave a quick look at the nginx repo. Looks like this logic might already be built-in?
https://github.com/nginx/docker-nginx/blob/master/entrypoint/15-local-resolvers.envsh
We might just need to change the conf to a template (& moved to proper folder) and use that var instead?

The resolver addition was ported after implementing the fix in HA add-on (that definitely needs it), but could be it just needs to be removed completely in plain Docker/Kube? Seeing the above, I'm thinking it might already be handled internally...
I'm not able to test this at the moment though.

@Nerivec
Copy link
Owner

Nerivec commented Sep 23, 2025

@mmssantos were you able to check if the resolver is needed at all in Docker & Kube (by just removing the line in conf)?

@mmssantos
Copy link
Author

@mmssantos were you able to check if the resolver is needed at all in Docker & Kube (by just removing the line in conf)?

Haven't been able to get my hands dirty on it again so far.
Trying to get some free time by end of week, will keep you posted.

@mmssantos
Copy link
Author

Apologies for the delay, time as been running low lately.
After testing a few extra things out and reading through the nginx documentation, it appears that when using a variable in the proxy_pass directive, nginx requires that a resolver directive exists inside the configuration and points to a valid dns server.

The entrypoint script "15-local-resolvers.envsh" present in the base nginx image is there to support these types of scenarios, requiring that an environment variable "NGINX_ENTRYPOINT_LOCAL_RESOLVERS" is set to true to activate.

I have added a few changes to the repo that, when the "NGINX_ENTRYPOINT_LOCAL_RESOLVERS" is set to true will grab the locally configured dns servers using the native script in the original nginx container image, substitute the placeholder "NGINX_LOCAL_RESOLVERS" in the added nginx.conf.template with the captured dns servers and then substitute the nginx.conf with the contents of the nginx.conf.template.
Using this approach, if the "NGINX_ENTRYPOINT_LOCAL_RESOLVERS" is not set at all, everything works like expected with the hardcoded "127.0.0.11" resolver directive and when it is set, to support, for example, execution inside Kubernetes, the local dns servers will be captured and properly configured in the nginx configuration.

@mmssantos mmssantos reopened this Oct 4, 2025
@Nerivec
Copy link
Owner

Nerivec commented Oct 4, 2025

We shouldn't duplicate the nginx.conf. Best to set the default in the script as needed and always use the template. Less maintenance and less error-prone.

hardcoded dns server "127.0.0.11" will be used, if it is set, local dns
servers will be grabbed and configured
@mmssantos
Copy link
Author

Added additional logic to the ".docker/scripts/100-envsubst-on-nginx-conf.sh" to fallback to "127.0.0.11" in case the environment variable "NGINX_ENTRYPOINT_LOCAL_RESOLVERS" is not set.
Wondering if we shouldn't just resort to always setting this environment variable to true and having the dynamic mechanism always run vs having this dual approach given that even inside docker "/etc/resolve.conf" should always have the 127.0.0.11 dns server configured. How do you feel about it?

@Nerivec
Copy link
Owner

Nerivec commented Oct 5, 2025

Can you take a look at the commit I pushed, from what I gathered from the container scripts, something like this should be the cleanest approach?
https://github.com/nginx/docker-nginx/blob/master/entrypoint/20-envsubst-on-templates.sh#L31

Using a custom solution will bypass the init scripts of the container. I think we should avoid that, keep the behavior in line with the base container, keep just a thing wrapper.

@mmssantos
Copy link
Author

mmssantos commented Oct 9, 2025

@Nerivec Reviewing all of the existing scripts inside the official Docker image and a few Issues on their github, it appears that the combination of the environment variable "NGINX_ENTRYPOINT_LOCAL_RESOLVERS=True", "15-local-resolvers.envsh", "20-envsubst-on-templates.sh" and a well placed .template file with a "resolver $NGINX_LOCAL_RESOLVERS ipv6=off;" directive on /etc/nginx/templates will indeed accomplish what we are looking for.

However, the way things are built at this point in time in the zigbee2mqtt-windfront container image will cause some issues, given that the official mechanism inside nginx will convert the template into a .conf inside /etc/nginx/conf.d.
The current nginx.conf does not include the load of the configuration file from /etc/nginx/conf.d so it will need to be adapted to support this new methodology.
Not really sure on how best to handle this in a way that is simple and introduces a low maintenance overhead. Maybe the best approach is to migrate the nginx configuration into a template and make it mandatory to have the "NGINX_ENTRYPOINT_LOCAL_RESOLVERS=True" environment variable set for proper execution of the container image in all environments give the need to use variables as part of the proxy_pass directive.

@Nerivec
Copy link
Owner

Nerivec commented Oct 9, 2025

That last commit includes conf.d/resolver.conf in nginx.conf
If I followed the scripts correctly, I think it should be all setup with just these few changes.

@mmssantos
Copy link
Author

Can confirm that with the changes in the last commit and the "NGINX_ENTRYPOINT_LOCAL_RESOLVERS=True" environment variable, everything works like expected.
If the environment variable is not set, nginx bring up fails due to the fact that the mechanism to process the template will generate a .conf file with "resolver $NGINX_LOCAL_RESOLVERS ipv6=off;" and bring up will fail with "host not found in resolver "$NGINX_LOCAL_RESOLVERS" in /etc/nginx/conf.d/resolver.conf".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hardcoded "resolver 127.0.0.11 ipv6=off;" line inside nginx.conf prevents zigbee2mqtt-windfront from properly running when deployed on Kubernetes

3 participants