diff --git a/nginx.tmpl b/nginx.tmpl index d861050..80327b0 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -120,6 +120,8 @@ server { {{ $host := trim $host }} {{ $is_regexp := hasPrefix "~" $host }} {{ $upstream_name := when $is_regexp (sha1 $host) $host }} +{{ $specific_port := eq (or ($.Env.VIRTUAL_HOST_SPECIFIC_PORT) "") "true" }} +{{ $server_name := when $specific_port (coalesce (index (split $host ":") 0) $host) $host }} # {{ $host }} upstream {{ $upstream_name }} { @@ -132,8 +134,13 @@ upstream {{ $upstream_name }} { {{ if (and (ne $containerNetwork.Name "ingress") (or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name "host"))) }} ## Can be connected with "{{ $containerNetwork.Name }}" network + {{ if $specific_port }} + {{/* If ports per virtual host specified, use that, falling back to standard web port $container.Env.VIRTUAL_PORT and 80 */}} + {{ $port := coalesce (index (split $host ":") 1) $container.Env.VIRTUAL_PORT "80" }} + {{ $address := where $container.Addresses "Port" $port | first }} + {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} {{/* If only 1 port exposed, use that */}} - {{ if eq $addrLen 1 }} + {{ else 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 */}} @@ -192,7 +199,7 @@ upstream {{ $upstream_name }} { {{ if eq $https_method "redirect" }} server { - server_name {{ $host }}; + server_name {{ $server_name }}; listen 80 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:80 {{ $default_server }}; @@ -203,7 +210,7 @@ server { {{ end }} server { - server_name {{ $host }}; + server_name {{ $server_name }}; listen 443 ssl http2 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:443 ssl http2 {{ $default_server }}; @@ -301,7 +308,7 @@ server { {{ if or (not $is_https) (eq $https_method "noredirect") }} server { - server_name {{ $host }}; + server_name {{ $server_name }}; listen 80 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:80 {{ $default_server }}; @@ -344,7 +351,7 @@ server { {{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { - server_name {{ $host }}; + server_name {{ $server_name }}; listen 443 ssl http2 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:443 ssl http2 {{ $default_server }}; diff --git a/test/test_specific-ports/test_specified_all.py b/test/test_specific-ports/test_specified_all.py new file mode 100644 index 0000000..f8b9c69 --- /dev/null +++ b/test/test_specific-ports/test_specified_all.py @@ -0,0 +1,16 @@ +import pytest + + +def test_unknown_virtual_host_is_503(docker_compose, nginxproxy): + r = nginxproxy.get("http://unknown.nginx-proxy.tld/port") + assert r.status_code == 503 + +def test_webA_is_forwarded(docker_compose, nginxproxy): + r = nginxproxy.get("http://webA.nginx-proxy.tld/port") + assert r.status_code == 200 + assert r.text == "answer from port 5000\n" + +def test_webB_is_forwarded(docker_compose, nginxproxy): + r = nginxproxy.get("http://webB.nginx-proxy.tld/port") + assert r.status_code == 200 + assert r.text == "answer from port 5001\n" diff --git a/test/test_specific-ports/test_specified_all.yml b/test/test_specific-ports/test_specified_all.yml new file mode 100644 index 0000000..0822863 --- /dev/null +++ b/test/test_specific-ports/test_specified_all.yml @@ -0,0 +1,15 @@ +web: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: webA.nginx-proxy.tld:5000,webB.nginx-proxy.tld:5001 + VIRTUAL_HOST_SPECIFIC_PORT: true + + +sut: + image: jwilder/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro diff --git a/test/test_specific-ports/test_specified_none.py b/test/test_specific-ports/test_specified_none.py new file mode 100644 index 0000000..411edd5 --- /dev/null +++ b/test/test_specific-ports/test_specified_none.py @@ -0,0 +1,16 @@ +import pytest + + +def test_unknown_virtual_host_is_503(docker_compose, nginxproxy): + r = nginxproxy.get("http://unknown.nginx-proxy.tld/port") + assert r.status_code == 503 + +def test_webA_is_forwarded(docker_compose, nginxproxy): + r = nginxproxy.get("http://webA.nginx-proxy.tld/port") + assert r.status_code == 200 + assert r.text == "answer from port 80\n" + +def test_webB_is_forwarded(docker_compose, nginxproxy): + r = nginxproxy.get("http://webB.nginx-proxy.tld/port") + assert r.status_code == 200 + assert r.text == "answer from port 80\n" diff --git a/test/test_specific-ports/test_specified_none.yml b/test/test_specific-ports/test_specified_none.yml new file mode 100644 index 0000000..1f7ad2b --- /dev/null +++ b/test/test_specific-ports/test_specified_none.yml @@ -0,0 +1,15 @@ +web: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: webA.nginx-proxy.tld,webB.nginx-proxy.tld + VIRTUAL_HOST_SPECIFIC_PORT: true + + +sut: + image: jwilder/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro