Ver código fonte

Honor VIRTUAL_PORT + DEBUG flag + fallback entry

The VIRTUAL_PORT environment variable should always be honored.
Even when the related port is not exposed.
Fix for nging-proxy/nginx-proxy#1132.

This commit also add the DEBUG environment variable which enables more
verbose comments in the nginx comfiguration file to help troubleshooting
unreachable containers.

Finaly it fixes nging-proxy/nginx-proxy#1105 as well by defining only one
fallback entry per upstream block.
Gilles Filippini 4 anos atrás
pai
commit
97a5dec57a
2 arquivos alterados com 62 adições e 27 exclusões
  1. 37 6
      README.md
  2. 25 21
      nginx.tmpl

+ 37 - 6
README.md

@@ -82,16 +82,20 @@ NginX does not support scoped IPv6 resolvers. In [docker-entrypoint.sh](./docker
 
 By default, docker uses IPv6-to-IPv4 NAT. This means all client connections from IPv6 addresses will show docker's internal IPv4 host address. To see true IPv6 client IP addresses, you must [enable IPv6](https://docs.docker.com/config/daemon/ipv6/) and use [ipv6nat](https://github.com/robbertkl/docker-ipv6nat). You must also disable the userland proxy by adding `"userland-proxy": false` to `/etc/docker/daemon.json` and restarting the daemon.
 
-### Multiple Ports
+### Multiple Hosts
 
-If your container exposes multiple ports, nginx-proxy will default to the service running on port 80.  If you need to specify a different port, you can set a VIRTUAL_PORT env var to select a different one.  If your container only exposes one port and it has a VIRTUAL_HOST env var set, that port will be selected.
+If you need to support multiple virtual hosts for a container, you can separate each entry with commas.  For example, `foo.bar.com,baz.bar.com,bar.com` and each host will be setup the same.
 
-  [1]: https://github.com/jwilder/docker-gen
-  [2]: http://jasonwilder.com/blog/2014/03/25/automated-nginx-reverse-proxy-for-docker/
+### Virtual Ports
 
-### Multiple Hosts
+When your container exposes only one port, nginx-proxy will default to this port, else to port 80.
 
-If you need to support multiple virtual hosts for a container, you can separate each entry with commas.  For example, `foo.bar.com,baz.bar.com,bar.com` and each host will be setup the same.
+If you need to specify a different port, you can set a `VIRTUAL_PORT` env var to select a different one. This variable cannot be set to more than one port.
+
+For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrieved by order of precedence:
+1. From the `VIRTUAL_PORT` environment variable
+1. From the container's exposed port if there is only one
+1. From the default port 80 when none of the above methods apply
 
 ### Wildcard Hosts
 
@@ -424,6 +428,33 @@ will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRT
 #### Per-VIRTUAL_HOST `server_tokens` configuration
 Per virtual-host `servers_tokens` directive can be configured by passing appropriate value to the `SERVER_TOKENS` environment variable. Please see the [nginx http_core module configuration](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) for more details.
 
+### Troubleshooting
+
+In case you can't access your VIRTUAL_HOST, set `DEBUG=true` in the client container's environment and have a look at the generated nginx configuration file `/etc/nginx/conf.d/default`:
+
+```
+$ docker exec <nginx-proxy-instance> cat /etc/nginx/conf.d/default
+```
+Especially at `upstream` definition blocks which should look like:
+
+```
+# foo.example.com
+upstream foo.example.com {
+	## Can be connected with "my_network" network
+	# Exposed ports: [{   <exposed_port1>  tcp } {   <exposed_port2>  tcp } ...]
+	# Default virtual port: <exposed_port|80>
+	# VIRTUAL_PORT: <VIRTUAL_PORT>
+	# foo
+	server 172.18.0.9:<Port>;
+	# Fallback entry
+	server 127.0.0.1 down;
+}
+```
+
+The effective `Port` is retrieved by order of precedence:
+1. From the `VIRTUAL_PORT` environment variable
+1. From the container's exposed port if there is only one
+1. From the default port 80 when none of the above methods apply
 
 ### Contributing
 

+ 25 - 21
nginx.tmpl

@@ -2,24 +2,25 @@
 
 {{ $external_http_port := coalesce $.Env.HTTP_PORT "80" }}
 {{ $external_https_port := coalesce $.Env.HTTPS_PORT "443" }}
+{{ $debug_all := $.Env.DEBUG }}
 
 {{ define "upstream" }}
 	{{ if .Address }}
 		{{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}}
 		{{ if and .Container.Node.ID .Address.HostPort }}
-			# {{ .Container.Node.Name }}/{{ .Container.Name }}
+	# {{ .Container.Node.Name }}/{{ .Container.Name }}
 			server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }};
 		{{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}}
 		{{ else if .Network }}
-			# {{ .Container.Name }}
-			server {{ .Network.IP }}:{{ .Address.Port }};
+	# {{ .Container.Name }}
+	server {{ .Network.IP }}:{{ .Address.Port }};
 		{{ end }}
 	{{ else if .Network }}
-		# {{ .Container.Name }}
+	# {{ .Container.Name }}
 		{{ if .Network.IP }}
-			server {{ .Network.IP }} down;
+	server {{ .Network.IP }}:{{ .VirtualPort }};
 		{{ else }}
-			server 127.0.0.1 down;
+	# /!\ No IP for this network!
 		{{ end }}
 	{{ end }}
 
@@ -180,29 +181,32 @@ server {
 upstream {{ $upstream_name }} {
 
 {{ range $container := $containers }}
-	{{ $addrLen := len $container.Addresses }}
-
+	{{ $debug := (eq (coalesce $container.Env.DEBUG $debug_all "false") "true") }}
+	{{/* If only 1 port exposed, use that as a default, else 80 */}}
+	{{ $defaultPort := (when (eq (len $container.Addresses) 1) (first $container.Addresses) (dict "Port" "80")).Port }}
 	{{ range $knownNetwork := $CurrentContainer.Networks }}
 		{{ range $containerNetwork := $container.Networks }}
 			{{ if (and (ne $containerNetwork.Name "ingress") (or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name "host"))) }}
-				## Can be connected with "{{ $containerNetwork.Name }}" network
-
-				{{/* If only 1 port exposed, use that */}}
-				{{ if eq $addrLen 1 }}
-					{{ $address := index $container.Addresses 0 }}
-					{{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
-				{{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}}
-				{{ else }}
-					{{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }}
-					{{ $address := where $container.Addresses "Port" $port | first }}
-					{{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
+	## Can be connected with "{{ $containerNetwork.Name }}" network
+				{{ $port := (coalesce $container.Env.VIRTUAL_PORT $defaultPort) }}
+				{{ $address := where $container.Addresses "Port" $port | first }}
+				{{ if $debug }}
+	# Exposed ports: {{ $container.Addresses }}
+	# Default virtual port: {{ $defaultPort }}
+	# VIRTUAL_PORT: {{ $container.Env.VIRTUAL_PORT }}
+					{{ if not $address }}
+	# /!\ Virtual port not exposed
+					{{ end }}
 				{{ end }}
+				{{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork "VirtualPort" $port) }}
 			{{ else }}
-				# Cannot connect to network of this container
-				server 127.0.0.1 down;
+	# Cannot connect to network '{{ $containerNetwork.Name }}' of this container
 			{{ end }}
 		{{ end }}
 	{{ end }}
+	{{/* nginx-proxy/nginx-proxy#1105 */}}
+	# Fallback entry
+	server 127.0.0.1 down;
 {{ end }}
 }