From c8bd35f6338629025f3c22ea8631387dfa3f2a61 Mon Sep 17 00:00:00 2001 From: Frederik Bosch Date: Mon, 30 Jul 2018 21:13:49 +0200 Subject: [PATCH] add specific port feature --- README.md | 6 ++++++ nginx.tmpl | 13 +++++++------ test/pytest.ini | 2 +- test/test_specific-ports/test_specified_all.yml | 10 ++++++---- .../test_specific-ports/test_specified_mixed.py | 16 ++++++++++++++++ .../test_specified_mixed.yml | 17 +++++++++++++++++ .../test_specific-ports/test_specified_none.yml | 9 +++++---- 7 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 test/test_specific-ports/test_specified_mixed.py create mode 100644 test/test_specific-ports/test_specified_mixed.yml diff --git a/README.md b/README.md index 054b4d1..523720d 100644 --- a/README.md +++ b/README.md @@ -401,6 +401,12 @@ If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=e If you want most of your virtual hosts to use a default single `location` block configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default_location` file. This file will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}_location` file associated with it. +#### Multiple ports per virtual host + +A container can expose multiple ports that you want to proxy to different host names. In order to achieve this, you need +to activate pass `VIRTUAL_HOST_SPECIFIC_PORT` with the value `true` to *nginx-proxy*. Then you can start start any container +and pass multiple host names and ports `VIRTUAL_HOST=subdomain1.youdomain.com,subdomain2.youdomain.com:5000` + ### Contributing Before submitting pull requests or issues, please check github to make sure an existing issue or pull request is not already open. diff --git a/nginx.tmpl b/nginx.tmpl index 80327b0..120cd72 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -119,9 +119,9 @@ 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 }} +{{ $is_specific_port := eq (or ($.Env.VIRTUAL_HOST_SPECIFIC_PORT) "") "true" }} +{{ $upstream_name := when (or $is_regexp $is_specific_port) (sha1 $host) $host }} +{{ $server_name := when $is_specific_port (index (split $host ":") 0) $host }} # {{ $host }} upstream {{ $upstream_name }} { @@ -134,9 +134,10 @@ 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" }} + {{ $split_host_port := split $host ":" }} + {{ if (and $is_specific_port (eq (len $split_host_port) 2)) }} + {{/* If ports per virtual host specified, use that */}} + {{ $port := index $split_host_port 1 }} {{ $address := where $container.Addresses "Port" $port | first }} {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} {{/* If only 1 port exposed, use that */}} diff --git a/test/pytest.ini b/test/pytest.ini index 30f3e19..c7a8d7c 100644 --- a/test/pytest.ini +++ b/test/pytest.ini @@ -1,3 +1,3 @@ [pytest] # disable the creation of the `.cache` folders -addopts = -p no:cacheprovider --ignore=requirements --ignore=certs -r s -v \ No newline at end of file +addopts = -k "specified_mixed" -p no:cacheprovider --ignore=requirements --ignore=certs -r s -v \ No newline at end of file diff --git a/test/test_specific-ports/test_specified_all.yml b/test/test_specific-ports/test_specified_all.yml index 188ecc2..db8af4b 100644 --- a/test/test_specific-ports/test_specified_all.yml +++ b/test/test_specific-ports/test_specified_all.yml @@ -1,15 +1,17 @@ web: image: web expose: - - "81" + - "5000" + - "5001" environment: - WEB_PORTS: 81 + WEB_PORTS: "5000 5001" 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 + - ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro + environment: + VIRTUAL_HOST_SPECIFIC_PORT: "true" diff --git a/test/test_specific-ports/test_specified_mixed.py b/test/test_specific-ports/test_specified_mixed.py new file mode 100644 index 0000000..086ed13 --- /dev/null +++ b/test/test_specific-ports/test_specified_mixed.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 5001\n" diff --git a/test/test_specific-ports/test_specified_mixed.yml b/test/test_specific-ports/test_specified_mixed.yml new file mode 100644 index 0000000..8218f99 --- /dev/null +++ b/test/test_specific-ports/test_specified_mixed.yml @@ -0,0 +1,17 @@ +web: + image: web + expose: + - "80" + - "5001" + environment: + WEB_PORTS: "80 5001" + VIRTUAL_HOST: webA.nginx-proxy.tld,webB.nginx-proxy.tld:5001 + + +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 + environment: + VIRTUAL_HOST_SPECIFIC_PORT: "true" diff --git a/test/test_specific-ports/test_specified_none.yml b/test/test_specific-ports/test_specified_none.yml index 4259e27..081db12 100644 --- a/test/test_specific-ports/test_specified_none.yml +++ b/test/test_specific-ports/test_specified_none.yml @@ -1,15 +1,16 @@ web: image: web expose: - - "81" + - "80" environment: - WEB_PORTS: 81 + WEB_PORTS: 80 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 + - ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro + environment: + VIRTUAL_HOST_SPECIFIC_PORT: "true"