Преглед изворни кода

Merge pull request #1736 from nginx-proxy/predictable-upstream

Revert to predictable upstream names, optional SHA1 names
Nicolas Duchon пре 3 година
родитељ
комит
8adbea8aec

+ 6 - 0
README.md

@@ -415,6 +415,12 @@ If you want most of your virtual hosts to use a default single `location` block
 #### 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.
 
+### Unhashed vs SHA1 upstream names
+
+By default the nginx configuration `upstream` blocks will use this block's corresponding hostname as a predictable name. However, this can cause issues in some setups (see [this issue](https://github.com/nginx-proxy/nginx-proxy/issues/1162)). In those cases you might want to switch to SHA1 names for the `upstream` blocks by setting the `SHA1_UPSTREAM_NAME` environment variable to `true` on the nginx-proxy container.
+
+Please note that using regular expressions in `VIRTUAL_HOST` will always result in a corresponding `upstream` block with an SHA1 name.
+
 ### 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`:

+ 3 - 1
nginx.tmpl

@@ -3,6 +3,7 @@
 {{ $external_http_port := coalesce $.Env.HTTP_PORT "80" }}
 {{ $external_https_port := coalesce $.Env.HTTPS_PORT "443" }}
 {{ $debug_all := $.Env.DEBUG }}
+{{ $sha1_upstream_name := parseBool (coalesce $.Env.SHA1_UPSTREAM_NAME "false") }}
 
 {{ define "ssl_policy" }}
 	{{ if eq .ssl_policy "Mozilla-Modern" }}
@@ -153,7 +154,8 @@ server {
 {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }}
 
 {{ $host := trim $host }}
-{{ $upstream_name := sha1 $host }}
+{{ $is_regexp := hasPrefix "~" $host }}
+{{ $upstream_name := when (or $is_regexp $sha1_upstream_name) (sha1 $host) $host }}
 
 # {{ $host }}
 upstream {{ $upstream_name }} {

+ 7 - 0
test/test_upstream-name/test_predictable-name.py

@@ -0,0 +1,7 @@
+import pytest
+import re
+
+
+def test_predictable_upstream_is_present_in_nginx_generated_conf(docker_compose, nginxproxy):
+    conf = nginxproxy.get_conf().decode('ASCII')
+    assert re.search(r"upstream web\.nginx-proxy\.tld \{", conf)

+ 16 - 0
test/test_upstream-name/test_predictable-name.yml

@@ -0,0 +1,16 @@
+version: '2'
+
+services:
+  web:
+    image: web
+    expose:
+      - "80"
+    environment:
+      WEB_PORTS: 80
+      VIRTUAL_HOST: web.nginx-proxy.tld
+
+  sut:
+    image: nginxproxy/nginx-proxy:test
+    volumes:
+      - /var/run/docker.sock:/tmp/docker.sock:ro
+      - ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro

+ 12 - 0
test/test_upstream-name/test_sha1-name.py

@@ -0,0 +1,12 @@
+import pytest
+import re
+
+
+def test_sha1_upstream_is_present_in_nginx_generated_conf(docker_compose, nginxproxy):
+    conf = nginxproxy.get_conf().decode('ASCII')
+    assert re.search(r"upstream 3e837201a6255962094cd6d8f61e22b07d3cc8ed \{", conf)
+
+def test_sha1_upstream_forwards_correctly(docker_compose, nginxproxy):
+    r = nginxproxy.get("http://web.nginx-proxy.tld/port")
+    assert r.status_code == 200   
+    assert r.text == "answer from port 80\n"

+ 18 - 0
test/test_upstream-name/test_sha1-name.yml

@@ -0,0 +1,18 @@
+version: '2'
+
+services:
+  web:
+    image: web
+    expose:
+      - "80"
+    environment:
+      WEB_PORTS: 80
+      VIRTUAL_HOST: web.nginx-proxy.tld
+
+  sut:
+    image: nginxproxy/nginx-proxy:test
+    volumes:
+      - /var/run/docker.sock:/tmp/docker.sock:ro
+      - ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro
+    environment:
+      SHA1_UPSTREAM_NAME: "true"