diff --git a/README.md b/README.md index a6504cd..99c2efb 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,10 @@ If your container exposes multiple ports, nginx-proxy will default to the servic 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. +### Manually Specifying Upstream IP + +In case you need to manually override the Upstream IP that Nginx will proxy to, you can declare a VIRTUAL_IP env var. If you do this, you also need to declare the VIRTUAL_PORT env variable as this switches the behaviour to a more "manual" declaration style. This is useful if one of your containers is in `network_mode: host` for instance. + ### Wildcard Hosts You can also use wildcards at the beginning and the end of host name, like `*.bar.com` or `foo.bar.*`. Or even a regular expression, which can be very useful in conjunction with a wildcard DNS service like [xip.io](http://xip.io), using `~^foo\.bar\..*\.xip\.io` will match `foo.bar.127.0.0.1.xip.io`, `foo.bar.10.0.2.2.xip.io` and all other given IPs. More information about this topic can be found in the nginx documentation about [`server_names`](http://nginx.org/en/docs/http/server_names.html). diff --git a/nginx.tmpl b/nginx.tmpl index d861050..2fab840 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,7 +1,10 @@ {{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }} {{ define "upstream" }} - {{ if .Address }} + {{ if and .IP .Port }} + # {{ .Container.Name }} with manually set IP + server {{ .IP }}:{{ .Port }}; + {{ else 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 }} @@ -19,7 +22,6 @@ server 127.0.0.1 down; {{ end }} {{ end }} - {{ end }} # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the @@ -126,28 +128,34 @@ upstream {{ $upstream_name }} { {{ range $container := $containers }} {{ $addrLen := len $container.Addresses }} + {{ if and $container.Env.VIRTUAL_IP $container.Env.VIRTUAL_HOST }} + # Manually defined upstream host and port + {{ $IP := coalesce $container.Env.VIRTUAL_IP "127.0.0.1" }} + {{ $Port := coalesce $container.Env.VIRTUAL_PORT "80" }} + {{ template "upstream" (dict "Container" $container "Port" $Port "IP" $IP) }} + {{ else }} + {{ 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 - {{ 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) }} - {{ end }} - {{ else }} - # Cannot connect to network of this container - server 127.0.0.1 down; - {{ end }} - {{ end }} - {{ end }} + {{/* 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) }} + {{ end }} + {{ else }} + # Cannot connect to network of this container + server 127.0.0.1 down; + {{ end }} + {{ end }} + {{ end }} + {{ end }} {{ end }} }