Configure runtime DNS resolution in Nginx

Refresh changing upstream addresses with resolver and variable proxy_pass, or use dynamic upstream resolution on supported Nginx versions.

Best practices
Illustration of server operations and request logs

For a changing backend hostname, configure runtime DNS resolution rather than relying on a name resolved when Nginx loads its configuration. A variable-based proxy_pass works on older releases; Nginx open source 1.27.3 and later also support resolve in an upstream group.

Neither approach means a DNS query for every HTTP request. Answers are cached according to their TTL or the configured valid override.

Use a variable and an explicit resolver

http {
    # Example private DNS address: replace with your trusted resolver.
    resolver 10.0.0.53 valid=30s;
    resolver_timeout 5s;

    server {
        listen 80;
        location / {
            set $backend dynamic.example.com;
            proxy_pass http://$backend;
            proxy_set_header Host $backend;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

The host header here identifies the backend hostname. Use $host instead only when the backend should receive the original public virtual host. For HTTPS upstreams, configure SNI and certificate verification for the upstream separately.

valid=30s overrides the DNS response TTL; it is not the minimum of TTL and 30 seconds. Omit it to use the response TTL. Short intervals improve freshness but increase resolver work and dependence on DNS availability.

The runtime resolver must be explicit. Point private service names at a DNS server that knows that private namespace. 127.0.0.53 works only if the systemd-resolved stub is reachable from Nginx's own network namespace; a host loopback address is not normally reachable as such inside another container.

Use ipv6=off only when you intentionally do not want AAAA lookups or IPv6 upstream use. A hostname having only an A record is not itself an error that requires disabling IPv6.

Use a dynamic upstream group on supported releases

For Nginx open source 1.27.3 or later:

upstream dynamic_backend {
    zone dynamic_backend 64k;
    resolver 10.0.0.53 valid=30s;
    server dynamic.example.com:8080 resolve;
}

server {
    listen 80;
    location / {
        proxy_pass http://dynamic_backend;
    }
}

Place the upstream and server blocks inside http. This retains upstream-group configuration while updating addresses. resolve was restricted to the commercial product before 1.27.3; check the installed version and module support before using it.

Verify changes and failures

Test configuration loading, successful requests, a controlled DNS address change, and DNS failure in a nonproduction environment. Inspect the upstream address and error messages; a 502 can also come from a refused connection or invalid response after resolution succeeds.

Variable proxy_pass with a URI component has different forwarding rules from a literal prefix mapping. The example omits that URI component to avoid replacing the request path accidentally.

FAQ

Does a five-second validity cause one DNS query per request?

No. Cached answers can serve many requests. DNS traffic still depends on workers, names, query types, expiry, and failures; do not assume a cache shared globally across all workers and hosts.

Can I just add resolver to a static proxy_pass?

For a literal hostname without a supported dynamic upstream configuration, adding resolver alone does not turn configuration-time resolution into periodic refresh. Use one of the explicit approaches above.

Where does this help?

Cloud load-balancer hostnames, service discovery, and dynamic DNS are common cases. It does not eliminate the need to coordinate DNS, backend readiness, and connection behavior during a rollout.

References: resolver caching, upstream resolve support, proxy_pass.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting