Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setup nginx not to crash if host in upstream is not found

People also ask

How does Nginx resolve upstream?

Upstream Domain Resolve¶ Its buffer has the latest IPs of the backend domain name and it integrates with the configured load balancing algorithm (least_conn, hash, etc) or the built in round robin if none is explicitly defined. At every interval (one second by default), it resolves the domain name.

What is upstream in Nginx configuration?

upstream defines a cluster that you can proxy requests to. It's commonly used for defining either a web server cluster for load balancing, or an app server cluster for routing / load balancing.

What is upstream address in nginx?

upstream. Defines the address and other parameters of a server. The address can be specified as a domain name or IP address, with an optional port, or as a UNIX-domain socket path specified after the “ unix: ” prefix. If a port is not specified, the port 80 is used.

Can we compress request to upstream in nginx?

By default, NGINX does not compress responses to proxied requests (requests that come from the proxy server). The fact that a request comes from a proxy server is determined by the presence of the Via header field in the request. To configure compression of these responses, use the gzip_proxied directive.


  1. If you can use a static IP then just use that, it'll startup and just return 503's if it doesn't respond.

  2. Use the resolver directive to point to something that can resolve the host, regardless if it's currently up or not.

  3. Resolve it at the location level, if you can't do the above (this will allow Nginx to start/run):

     location /foo {
       resolver 127.0.0.1 valid=30s;
       # or some other DNS (your company's internal DNS server)
       #resolver 8.8.8.8 valid=30s;
       set $upstream_foo foo;
       proxy_pass http://$upstream_foo:80;
     }
    
     location /bar {
       resolver 127.0.0.1 valid=30s;
       # or some other DNS (your company's internal DNS server)
       #resolver 8.8.8.8 valid=30s;
       set $upstream_bar foo;
       proxy_pass http://$upstream_bar:80;
     }
    

For me, option 3 of the answer from @Justin/@duskwuff solved the problem, but I had to change the resolver IP to 127.0.0.11 (Docker's DNS server):

location /foo {
  resolver 127.0.0.11 valid=30s;
  set $upstream_foo foo;
  proxy_pass http://$upstream_foo:80;
}

location /bar {
  resolver 127.0.0.11 valid=30s;
  set $upstream_bar foo;
  proxy_pass http://$upstream_bar:80;
}

But as @Justin/@duskwuff mentioned, you could use any other external DNS server.


The main advantage of using upstream is to define a group of servers than can listen on different ports and configure load-balancing and failover between them.

In your case you are only defining 1 primary server per upstream so it must to be up.

Instead, use variables for your proxy_pass(es) and remember to handle the possible errors (404s, 503s) that you might get when a target server is down.


Another quick and easy fix for someone's scenario, i can start and stop without my main server bombing out

    extra_hosts:
      - "dockerhost:172.20.0.1" # <-- static ipv4 gateway of the network ip here thats the only sorta downside but it works for me, you can ifconfig inside a container with the network to find yours, kinda a noob answer but it helped me
    networks:
      - my_network
server {
  listen 80;
  server_name servername;

  location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;

    proxy_pass https://dockerhost:12345;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}