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

Solution 1:

  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;
     }
    

Solution 2:

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.

Solution 3:

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.

Solution 4:

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";
  }
}

Solution 5:

Bases on Justin's answer, the fastest way to do the trick is to replace final host with an IP address. You need to assign a static IP address to each container with --ip 172.18.0.XXX parameter. NGINX won't crash at startup and will simply respond with 502 error if host is not available.

Run container with static IP:

docker run --ip 172.18.0.XXX something

Nginx config:

location /foo {
    proxy_pass http://172.18.0.XXX:80;
}

Refer to this post how to setup a subnet with Docker.