From 75528bdfcbde2f341824787fa075e7599032fcb4 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Tue, 21 Dec 2021 18:36:21 +1300 Subject: [PATCH 01/71] chore: Refactor checksum comparisons - Use a DRY method instead. - ENV test changed from 2048-bit to 3072-bit to avoid confusion in a future test that should not be mixed up accidentally with 2048-bit elsewhere. - Custom DH file test comparison changed to match other comparisons for equality against the expected DH param content. - Related comments revised, additional comment for context added by the test definition. - Minor white-space adjustments. --- test/test_ssl/test_dhparam.py | 40 ++++++++++++++++++++++++---------- test/test_ssl/test_dhparam.yml | 6 ++--- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/test/test_ssl/test_dhparam.py b/test/test_ssl/test_dhparam.py index 6de92b2..64b26ae 100644 --- a/test/test_ssl/test_dhparam.py +++ b/test/test_ssl/test_dhparam.py @@ -101,6 +101,13 @@ def cannot_negotiate_dhe_ciphersuite(sut_container): assert "X25519" in r3 +def should_be_equivalent_content(sut_container, expected, actual): + expected_checksum = sut_container.exec_run(f"md5sum {expected}").output.split()[0] + actual_checksum = sut_container.exec_run(f"md5sum {actual}").output.split()[0] + + assert expected_checksum == actual_checksum + + # Parse array of container ENV, splitting at the `=` and returning the value, otherwise `None` def get_env(sut_container, var): env = sut_container.attrs['Config']['Env'] @@ -125,14 +132,17 @@ def test_default_dhparam_is_ffdhe4096(docker_compose): assert_log_contains("Setting up DH Parameters..", container_name) - # Make sure the dhparam file used is the default ffdhe4096.pem: - default_checksum = sut_container.exec_run("md5sum /app/dhparam/ffdhe4096.pem").output.split() - current_checksum = sut_container.exec_run("md5sum /etc/nginx/dhparam/dhparam.pem").output.split() - assert default_checksum[0] == current_checksum[0] + # `dhparam.pem` contents should match the default (ffdhe4096.pem): + should_be_equivalent_content( + sut_container, + "/app/dhparam/ffdhe4096.pem", + "/etc/nginx/dhparam/dhparam.pem" + ) can_negotiate_dhe_ciphersuite(sut_container) +# Overrides default DH group via ENV `DHPARAM_BITS=3072`: def test_can_change_dhparam_group(docker_compose): container_name="dh-env" sut_container = docker_client.containers.get(container_name) @@ -140,10 +150,12 @@ def test_can_change_dhparam_group(docker_compose): assert_log_contains("Setting up DH Parameters..", container_name) - # Make sure the dhparam file used is ffdhe2048.pem, not the default (ffdhe4096.pem): - default_checksum = sut_container.exec_run("md5sum /app/dhparam/ffdhe2048.pem").output.split() - current_checksum = sut_container.exec_run("md5sum /etc/nginx/dhparam/dhparam.pem").output.split() - assert default_checksum[0] == current_checksum[0] + # `dhparam.pem` contents should not match the default (ffdhe4096.pem): + should_be_equivalent_content( + sut_container, + "/app/dhparam/ffdhe3072.pem", + "/etc/nginx/dhparam/dhparam.pem" + ) can_negotiate_dhe_ciphersuite(sut_container) @@ -162,6 +174,7 @@ def test_fail_if_dhparam_group_not_supported(docker_compose): ) +# Overrides default DH group by providing a custom `/etc/nginx/dhparam/dhparam.pem`: def test_custom_dhparam_is_supported(docker_compose): container_name="dh-file" sut_container = docker_client.containers.get(container_name) @@ -172,10 +185,12 @@ def test_custom_dhparam_is_supported(docker_compose): container_name ) - # Make sure the dhparam file used is not the default (ffdhe4096.pem): - default_checksum = sut_container.exec_run("md5sum /app/dhparam/ffdhe4096.pem").output.split() - current_checksum = sut_container.exec_run("md5sum /etc/nginx/dhparam/dhparam.pem").output.split() - assert default_checksum[0] != current_checksum[0] + # `dhparam.pem` contents should not match the default (ffdhe4096.pem): + should_be_equivalent_content( + sut_container, + "/app/dhparam/ffdhe3072.pem", + "/etc/nginx/dhparam/dhparam.pem" + ) can_negotiate_dhe_ciphersuite(sut_container) @@ -189,6 +204,7 @@ def test_can_skip_dhparam(docker_compose): cannot_negotiate_dhe_ciphersuite(sut_container) + def test_can_skip_dhparam_backward_compatibility(docker_compose): container_name="dh-skip-backward" sut_container = docker_client.containers.get(container_name) diff --git a/test/test_ssl/test_dhparam.yml b/test/test_ssl/test_dhparam.yml index d49afc9..c8b0a85 100644 --- a/test/test_ssl/test_dhparam.yml +++ b/test/test_ssl/test_dhparam.yml @@ -19,7 +19,7 @@ with_default_group: with_alternative_group: container_name: dh-env environment: - - DHPARAM_BITS=2048 + - DHPARAM_BITS=3072 image: *img-nginxproxy volumes: *vols-common @@ -33,7 +33,7 @@ with_invalid_group: with_custom_file: container_name: dh-file image: *img-nginxproxy - volumes: + volumes: - *docker-sock - *nginx-certs - ../../dhparam/ffdhe3072.pem:/etc/nginx/dhparam/dhparam.pem:ro @@ -50,4 +50,4 @@ with_skip_backward: environment: - DHPARAM_GENERATION=false image: *img-nginxproxy - volumes: *vols-common \ No newline at end of file + volumes: *vols-common From 0f15130476412664c0ce41bbad2456d6dbae25f3 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Tue, 21 Dec 2021 17:38:38 +1300 Subject: [PATCH 02/71] tests: Verify correct DH group size when negotiating Additionally allows for adding extra openssl params when needed. --- test/test_ssl/test_dhparam.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/test/test_ssl/test_dhparam.py b/test/test_ssl/test_dhparam.py index 64b26ae..ee83214 100644 --- a/test/test_ssl/test_dhparam.py +++ b/test/test_ssl/test_dhparam.py @@ -80,12 +80,17 @@ def negotiate_cipher(sut_container, additional_params='', grep='Cipher is'): raise Exception("Failed to process CLI request:\n" + e.stderr) from None -def can_negotiate_dhe_ciphersuite(sut_container): - r = negotiate_cipher(sut_container, "-cipher 'EDH'") +# The default `dh_bits` can vary due to configuration. +# `additional_params` allows for adjusting the request to a specific `VIRTUAL_HOST`, +# where DH size can differ from the configured global default DH size. +def can_negotiate_dhe_ciphersuite(sut_container, dh_bits=4096, additional_params=''): + openssl_params = f"-cipher 'EDH' {additional_params}" + + r = negotiate_cipher(sut_container, openssl_params) assert "New, TLSv1.2, Cipher is DHE-RSA-AES256-GCM-SHA384\n" == r - r2 = negotiate_cipher(sut_container, "-cipher 'EDH'", "Server Temp Key") - assert "DH" in r2 + r2 = negotiate_cipher(sut_container, openssl_params, "Server Temp Key") + assert f"Server Temp Key: DH, {dh_bits} bits" in r2 def cannot_negotiate_dhe_ciphersuite(sut_container): @@ -139,7 +144,7 @@ def test_default_dhparam_is_ffdhe4096(docker_compose): "/etc/nginx/dhparam/dhparam.pem" ) - can_negotiate_dhe_ciphersuite(sut_container) + can_negotiate_dhe_ciphersuite(sut_container, 4096) # Overrides default DH group via ENV `DHPARAM_BITS=3072`: @@ -157,7 +162,7 @@ def test_can_change_dhparam_group(docker_compose): "/etc/nginx/dhparam/dhparam.pem" ) - can_negotiate_dhe_ciphersuite(sut_container) + can_negotiate_dhe_ciphersuite(sut_container, 3072) def test_fail_if_dhparam_group_not_supported(docker_compose): @@ -192,7 +197,7 @@ def test_custom_dhparam_is_supported(docker_compose): "/etc/nginx/dhparam/dhparam.pem" ) - can_negotiate_dhe_ciphersuite(sut_container) + can_negotiate_dhe_ciphersuite(sut_container, 3072) def test_can_skip_dhparam(docker_compose): From 9dc9d90d34b4d47b4b2ca975235f12a6b7a220b2 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Tue, 21 Dec 2021 17:50:58 +1300 Subject: [PATCH 03/71] tests: Verify site-specific DH params feature works correctly This addition requires usage of `DEFAULT_HOST` on containers tested to ensure they don't accidentally use `web2` as their default fallback (due to no SNI / `-servername` requested in openssl queries), otherwise they would be testing against the incorrect DH params response. They could alternatively request an FQDN explicitly as well, instead of relying on implicit fallback/default server selection behaviour. --- `web2.nginx-proxy.tld.dhparam.pem` is a copy of `ffdhe2048.pem`. --- .../certs/web2.nginx-proxy.tld.dhparam.pem | 8 +++++++ test/test_ssl/test_dhparam.py | 24 +++++++++++++++++++ test/test_ssl/test_dhparam.yml | 20 ++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 test/test_ssl/certs/web2.nginx-proxy.tld.dhparam.pem diff --git a/test/test_ssl/certs/web2.nginx-proxy.tld.dhparam.pem b/test/test_ssl/certs/web2.nginx-proxy.tld.dhparam.pem new file mode 100644 index 0000000..088f967 --- /dev/null +++ b/test/test_ssl/certs/web2.nginx-proxy.tld.dhparam.pem @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== +-----END DH PARAMETERS----- \ No newline at end of file diff --git a/test/test_ssl/test_dhparam.py b/test/test_ssl/test_dhparam.py index ee83214..c95af6e 100644 --- a/test/test_ssl/test_dhparam.py +++ b/test/test_ssl/test_dhparam.py @@ -200,6 +200,30 @@ def test_custom_dhparam_is_supported(docker_compose): can_negotiate_dhe_ciphersuite(sut_container, 3072) +# Only `web2` has a site-specific DH param file (which overrides all other DH config) +# Other tests here use `web5` explicitly, or implicitly (via ENV `DEFAULT_HOST`, otherwise first HTTPS server) +def test_custom_dhparam_is_supported_per_site(docker_compose): + container_name="dh-file" + sut_container = docker_client.containers.get(container_name) + assert sut_container.status == "running" + + # A site specific `dhparam.pem` with DH group size of 2048-bit. + # DH group size should not match the: + # - 4096-bit default. + # - 3072-bit default, overriden by file. + should_be_equivalent_content( + sut_container, + "/app/dhparam/ffdhe2048.pem", + "/etc/nginx/certs/web2.nginx-proxy.tld.dhparam.pem" + ) + + # `-servername` required for nginx-proxy to respond with site-specific DH params used: + can_negotiate_dhe_ciphersuite(sut_container, 2048, '-servername web2.nginx-proxy.tld') + + +# NOTE: These two tests will fail without the ENV `DEFAULT_HOST` to prevent +# accidentally falling back to `web2` as the default server, which has explicit DH params configured. +# Only copying DH params is skipped, not explicit usage via user providing custom files. def test_can_skip_dhparam(docker_compose): container_name="dh-skip" sut_container = docker_client.containers.get(container_name) diff --git a/test/test_ssl/test_dhparam.yml b/test/test_ssl/test_dhparam.yml index c8b0a85..fa4fe1e 100644 --- a/test/test_ssl/test_dhparam.yml +++ b/test/test_ssl/test_dhparam.yml @@ -6,12 +6,27 @@ web5: WEB_PORTS: "85" VIRTUAL_HOST: "web5.nginx-proxy.tld" +# Intended for testing with `dh-file` container. +# VIRTUAL_HOST is paired with site-specific DH param file. +# DEFAULT_HOST is required to avoid defaulting to web2, +# if not specifying FQDN (`-servername`) in openssl queries. +web2: + image: web + expose: + - "85" + environment: + WEB_PORTS: "85" + VIRTUAL_HOST: "web2.nginx-proxy.tld" + + # sut - System Under Test # `docker.sock` required for functionality # `certs` required to enable HTTPS via template with_default_group: container_name: dh-default image: &img-nginxproxy nginxproxy/nginx-proxy:test + environment: &env-common + - &default-host DEFAULT_HOST=web5.nginx-proxy.tld volumes: &vols-common - &docker-sock /var/run/docker.sock:/tmp/docker.sock:ro - &nginx-certs ./certs:/etc/nginx/certs:ro @@ -20,6 +35,7 @@ with_alternative_group: container_name: dh-env environment: - DHPARAM_BITS=3072 + - *default-host image: *img-nginxproxy volumes: *vols-common @@ -27,12 +43,14 @@ with_invalid_group: container_name: invalid-group-1024 environment: - DHPARAM_BITS=1024 + - *default-host image: *img-nginxproxy volumes: *vols-common with_custom_file: container_name: dh-file image: *img-nginxproxy + environment: *env-common volumes: - *docker-sock - *nginx-certs @@ -42,6 +60,7 @@ with_skip: container_name: dh-skip environment: - DHPARAM_SKIP=true + - *default-host image: *img-nginxproxy volumes: *vols-common @@ -49,5 +68,6 @@ with_skip_backward: container_name: dh-skip-backward environment: - DHPARAM_GENERATION=false + - *default-host image: *img-nginxproxy volumes: *vols-common From c5166f580e61442668bd1223a1867ecd0882e809 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Tue, 21 Dec 2021 18:00:39 +1300 Subject: [PATCH 04/71] tests: Add utility method to verify TLS chain of trust --- test/test_ssl/test_dhparam.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/test_ssl/test_dhparam.py b/test/test_ssl/test_dhparam.py index c95af6e..2f69ad3 100644 --- a/test/test_ssl/test_dhparam.py +++ b/test/test_ssl/test_dhparam.py @@ -1,5 +1,6 @@ import re import subprocess +import os import backoff import docker @@ -106,6 +107,22 @@ def cannot_negotiate_dhe_ciphersuite(sut_container): assert "X25519" in r3 +# To verify self-signed certificates, the file path to their CA cert must be provided. +# Use the `fqdn` arg to specify the `VIRTUAL_HOST` to request for verification for that cert. +# +# Resolves the following stderr warnings regarding self-signed cert verification and missing SNI: +# `Can't use SSL_get_servername` +# `verify error:num=20:unable to get local issuer certificate` +# `verify error:num=21:unable to verify the first certificate` +# +# The stderr output is hidden due to running the openssl command with `stderr=subprocess.PIPE`. +def can_verify_chain_of_trust(sut_container, ca_cert, fqdn): + openssl_params = f"-CAfile '{ca_cert}' -servername '{fqdn}'" + + r = negotiate_cipher(sut_container, openssl_params, "Verify return code") + assert "Verify return code: 0 (ok)" in r + + def should_be_equivalent_content(sut_container, expected, actual): expected_checksum = sut_container.exec_run(f"md5sum {expected}").output.split()[0] actual_checksum = sut_container.exec_run(f"md5sum {actual}").output.split()[0] @@ -220,6 +237,15 @@ def test_custom_dhparam_is_supported_per_site(docker_compose): # `-servername` required for nginx-proxy to respond with site-specific DH params used: can_negotiate_dhe_ciphersuite(sut_container, 2048, '-servername web2.nginx-proxy.tld') + # --Unrelated to DH support-- + # - `web5` is missing a certificate, but falls back to available `/etc/nginx/certs/nginx-proxy.tld.crt` via `nginx.tmpl` "closest" result. + # - `web2` has it's own cert provisioned at `/etc/nginx/certs/web2.nginx-proxy.tld.crt`. + can_verify_chain_of_trust( + sut_container, + ca_cert = f"{os.getcwd()}/certs/ca-root.crt", + fqdn = 'web2.nginx-proxy.tld' + ) + # NOTE: These two tests will fail without the ENV `DEFAULT_HOST` to prevent # accidentally falling back to `web2` as the default server, which has explicit DH params configured. From 0493e799f4b30536594ee7d9f603769e2ce81d2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Dec 2021 04:08:35 +0000 Subject: [PATCH 05/71] chore(deps): bump nginx from 1.21.4 to 1.21.5 Bumps nginx from 1.21.4 to 1.21.5. --- updated-dependencies: - dependency-name: nginx dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8005b95..95db046 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ && rm -rf /go/forego # Build the final image -FROM nginx:1.21.4 +FROM nginx:1.21.5 LABEL maintainer="Nicolas Duchon (@buchdag)" # Install wget and install/updates certificates diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 75250f6..81fd9d3 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -37,7 +37,7 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ && rm -rf /go/forego # Build the final image -FROM nginx:1.21.4-alpine +FROM nginx:1.21.5-alpine LABEL maintainer="Nicolas Duchon (@buchdag)" # Install wget and install/updates certificates From 93c04dce8df3025f77912c5d93d99e619172266c Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Fri, 31 Dec 2021 20:43:02 +1300 Subject: [PATCH 06/71] fix: Properly detect pytest running via container The original `/.dockerenv` approach is no longer valid, and context wise we're only using this for the test suite, so using an ENV in that container is a better solution. --- test/conftest.py | 10 +++++----- test/requirements/Dockerfile-nginx-proxy-tester | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 3e0f3af..438210e 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -23,7 +23,7 @@ logging.getLogger('DNS').setLevel(logging.DEBUG) logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(logging.WARN) CA_ROOT_CERTIFICATE = os.path.join(os.path.dirname(__file__), 'certs/ca-root.crt') -I_AM_RUNNING_INSIDE_A_DOCKER_CONTAINER = os.path.isfile("/.dockerenv") +PYTEST_RUNNING_IN_CONTAINER = os.environ.get('PYTEST_RUNNING_IN_CONTAINER') == "1" FORCE_CONTAINER_IPV6 = False # ugly global state to consider containers' IPv6 address instead of IPv4 @@ -259,7 +259,7 @@ def restore_urllib_dns_resolver(getaddrinfo_func): def remove_all_containers(): for container in docker_client.containers.list(all=True): - if I_AM_RUNNING_INSIDE_A_DOCKER_CONTAINER and container.id.startswith(socket.gethostname()): + if PYTEST_RUNNING_IN_CONTAINER and container.id.startswith(socket.gethostname()): continue # pytest is running within a Docker container, so we do not want to remove that particular container logging.info(f"removing container {container.name}") container.remove(v=True, force=True) @@ -349,7 +349,7 @@ def connect_to_network(network): :return: the name of the network we were connected to, or None """ - if I_AM_RUNNING_INSIDE_A_DOCKER_CONTAINER: + if PYTEST_RUNNING_IN_CONTAINER: try: my_container = docker_client.containers.get(socket.gethostname()) except docker.errors.NotFound: @@ -372,7 +372,7 @@ def disconnect_from_network(network=None): :param network: name of a docker network to disconnect from """ - if I_AM_RUNNING_INSIDE_A_DOCKER_CONTAINER and network is not None: + if PYTEST_RUNNING_IN_CONTAINER and network is not None: try: my_container = docker_client.containers.get(socket.gethostname()) except docker.errors.NotFound: @@ -394,7 +394,7 @@ def connect_to_all_networks(): :return: a list of networks we connected to """ - if not I_AM_RUNNING_INSIDE_A_DOCKER_CONTAINER: + if not PYTEST_RUNNING_IN_CONTAINER: return [] else: # find the list of docker networks diff --git a/test/requirements/Dockerfile-nginx-proxy-tester b/test/requirements/Dockerfile-nginx-proxy-tester index 3c25c0c..36984fe 100644 --- a/test/requirements/Dockerfile-nginx-proxy-tester +++ b/test/requirements/Dockerfile-nginx-proxy-tester @@ -1,5 +1,7 @@ FROM python:3.9 +ENV PYTEST_RUNNING_IN_CONTAINER=1 + COPY python-requirements.txt /requirements.txt RUN pip install -r /requirements.txt From e748d53a1f614b5210143e00202daf6c1219e127 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Fri, 31 Dec 2021 21:51:40 +1300 Subject: [PATCH 07/71] chore: Extract hostname access to a var DRY and clearer that we're referring to the pytest container. --- test/conftest.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 438210e..2212ba4 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -28,6 +28,7 @@ FORCE_CONTAINER_IPV6 = False # ugly global state to consider containers' IPv6 a docker_client = docker.from_env() +test_container = socket.gethostname() ############################################################################### @@ -259,7 +260,7 @@ def restore_urllib_dns_resolver(getaddrinfo_func): def remove_all_containers(): for container in docker_client.containers.list(all=True): - if PYTEST_RUNNING_IN_CONTAINER and container.id.startswith(socket.gethostname()): + if PYTEST_RUNNING_IN_CONTAINER and container.id.startswith(test_container): continue # pytest is running within a Docker container, so we do not want to remove that particular container logging.info(f"removing container {container.name}") container.remove(v=True, force=True) @@ -351,9 +352,9 @@ def connect_to_network(network): """ if PYTEST_RUNNING_IN_CONTAINER: try: - my_container = docker_client.containers.get(socket.gethostname()) + my_container = docker_client.containers.get(test_container) except docker.errors.NotFound: - logging.warn(f"container {socket.gethostname()!r} not found") + logging.warn(f"container {test_container} not found") return # figure out our container networks @@ -374,9 +375,9 @@ def disconnect_from_network(network=None): """ if PYTEST_RUNNING_IN_CONTAINER and network is not None: try: - my_container = docker_client.containers.get(socket.gethostname()) + my_container = docker_client.containers.get(test_container) except docker.errors.NotFound: - logging.warn(f"container {socket.gethostname()!r} not found") + logging.warn(f"container {test_container} not found") return # figure out our container networks From b2b4c7199730baa86996fececaedeb70d4618198 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Fri, 31 Dec 2021 22:12:25 +1300 Subject: [PATCH 08/71] fix: Don't remove pytest container when running with host network mode When the container runs with host networking instead of the default bridge, the `$HOSTNAME` / `/etc/hostname` reflects that of the host instead of the container ID , which causes the pytest container to get removed accidentally. Using a container name instead we can more reliably target the container to avoid removing it, should we need to run with host networking instead. --- test/conftest.py | 6 ++++-- test/pytest.sh | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 2212ba4..b8db538 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -28,7 +28,9 @@ FORCE_CONTAINER_IPV6 = False # ugly global state to consider containers' IPv6 a docker_client = docker.from_env() -test_container = socket.gethostname() + +# Name of pytest container to reference if it's being used for running tests +test_container = 'nginx-proxy-pytest' ############################################################################### @@ -260,7 +262,7 @@ def restore_urllib_dns_resolver(getaddrinfo_func): def remove_all_containers(): for container in docker_client.containers.list(all=True): - if PYTEST_RUNNING_IN_CONTAINER and container.id.startswith(test_container): + if PYTEST_RUNNING_IN_CONTAINER and container.name == test_container: continue # pytest is running within a Docker container, so we do not want to remove that particular container logging.info(f"removing container {container.name}") container.remove(v=True, force=True) diff --git a/test/pytest.sh b/test/pytest.sh index 99c054c..28275e5 100755 --- a/test/pytest.sh +++ b/test/pytest.sh @@ -18,8 +18,8 @@ docker build -t nginx-proxy-tester -f "${DIR}/requirements/Dockerfile-nginx-prox # run the nginx-proxy-tester container setting the correct value for the working dir in order for # docker-compose to work properly when run from within that container. -exec docker run --rm -it \ ---volume /var/run/docker.sock:/var/run/docker.sock \ ---volume "${DIR}:${DIR}" \ ---workdir "${DIR}" \ -nginx-proxy-tester "${ARGS[@]}" \ No newline at end of file +exec docker run --rm -it --name "nginx-proxy-pytest" \ + --volume "/var/run/docker.sock:/var/run/docker.sock" \ + --volume "${DIR}:${DIR}" \ + --workdir "${DIR}" \ + nginx-proxy-tester "${ARGS[@]}" \ No newline at end of file From 0e5d97a268a7dac6151631ce664cadf201b84fa9 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Fri, 31 Dec 2021 22:14:26 +1300 Subject: [PATCH 09/71] fix: Don't connect pytest container to networks when using host network This is not compatible or required, since host networking is no longer isolated to container networks only. --- test/conftest.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/conftest.py b/test/conftest.py index b8db538..3f5f04c 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -362,6 +362,10 @@ def connect_to_network(network): # figure out our container networks my_networks = list(my_container.attrs["NetworkSettings"]["Networks"].keys()) + # If the pytest container is using host networking, it cannot connect to container networks (not required with host network) + if 'host' in my_networks: + return None + # make sure our container is connected to the nginx-proxy's network if network not in my_networks: logging.info(f"Connecting to docker network: {network.name}") From 04b0181980c0ec51accede0618a53788959e3d95 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Fri, 31 Dec 2021 22:30:49 +1300 Subject: [PATCH 10/71] fix: Ensure networks are actually connected to pytest container The `network` object would never be in a list of network names (strings), and without `greedy=True` arg as the `docker-py` API docs note, the containers will not be part of the results, thus always returning an empty list which was not intended.. Now the network will properly match the current networks for pytest container, avoiding duplicate connect attempts, and the network list result will actually have containers to count when filtering by length. --- test/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 3f5f04c..fce4cde 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -367,7 +367,7 @@ def connect_to_network(network): return None # make sure our container is connected to the nginx-proxy's network - if network not in my_networks: + if network.name not in my_networks: logging.info(f"Connecting to docker network: {network.name}") network.connect(my_container) return network @@ -405,7 +405,7 @@ def connect_to_all_networks(): return [] else: # find the list of docker networks - networks = [network for network in docker_client.networks.list() if len(network.containers) > 0 and network.name != 'bridge'] + networks = [network for network in docker_client.networks.list(greedy=True) if len(network.containers) > 0 and network.name != 'bridge'] return [connect_to_network(network) for network in networks] From 115461744b931f81f175b5f2ed3b17e74179e1f8 Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Sat, 1 Jan 2022 01:38:13 +1300 Subject: [PATCH 11/71] fix: Skip IPv6 when forced but not available + avoid `none` network A test on raw IP addresses doesn't reach the existing IPv6 skip logic, added that to avoid a test failing when only IPv4 is available (eg: standard docker container networks). Additionally some other tests set the `none` network and connecting to this fails as it's not allowed? Preventing that from happening resolves the final failing tests within containerized pytest. --- test/conftest.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index fce4cde..dda8379 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -239,6 +239,11 @@ def monkey_patch_urllib_dns_resolver(): logging.getLogger('DNS').debug(f"resolving domain name {repr(args)}") _args = list(args) + # Fail early when querying IP directly and it is forced ipv6 when not supported, + # Otherwise a pytest container not using the host network fails to pass `test_raw-ip-vhost`. + if FORCE_CONTAINER_IPV6 and not HAS_IPV6: + pytest.skip("This system does not support IPv6") + # custom DNS resolvers ip = nginx_proxy_dns_resolver(args[0]) if ip is None: @@ -366,8 +371,9 @@ def connect_to_network(network): if 'host' in my_networks: return None - # make sure our container is connected to the nginx-proxy's network - if network.name not in my_networks: + # Make sure our container is connected to the nginx-proxy's network, + # but avoid connecting to `none` network (not valid) with `test_server-down` tests + if network.name not in my_networks and network.name != 'none': logging.info(f"Connecting to docker network: {network.name}") network.connect(my_container) return network From 6b3ee66783889599f96c43807792e15c2b01bb0d Mon Sep 17 00:00:00 2001 From: polarathene <5098581+polarathene@users.noreply.github.com> Date: Sat, 1 Jan 2022 01:39:51 +1300 Subject: [PATCH 12/71] chore: white-space housekeeping Noticed some trailing white-space. Removed for consistency with the rest of the file. --- test/conftest.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index dda8379..cf26b30 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -34,9 +34,9 @@ test_container = 'nginx-proxy-pytest' ############################################################################### -# +# # utilities -# +# ############################################################################### @contextlib.contextmanager @@ -60,7 +60,7 @@ def ipv6(force_ipv6=True): class requests_for_docker(object): """ - Proxy for calling methods of the requests module. + Proxy for calling methods of the requests module. When a HTTP response failed due to HTTP Error 404 or 502, retry a few times. Provides method `get_conf` to extract the nginx-proxy configuration content. """ @@ -224,7 +224,7 @@ def docker_container_dns_resolver(domain_name): ip = container_ip(container) log.info(f"resolving domain name {domain_name!r} as IP address {ip} of container {container.name}") - return ip + return ip def monkey_patch_urllib_dns_resolver(): @@ -306,7 +306,7 @@ def docker_compose_down(compose_file='docker-compose.yml'): def wait_for_nginxproxy_to_be_ready(): """ - If one (and only one) container started from image nginxproxy/nginx-proxy:test is found, + If one (and only one) container started from image nginxproxy/nginx-proxy:test is found, wait for its log to contain substring "Watching docker events" """ containers = docker_client.containers.list(filters={"ancestor": "nginxproxy/nginx-proxy:test"}) @@ -416,18 +416,18 @@ def connect_to_all_networks(): ############################################################################### -# +# # Py.test fixtures -# +# ############################################################################### @pytest.fixture(scope="module") def docker_compose(request): """ pytest fixture providing containers described in a docker compose file. After the tests, remove the created containers - + A custom docker compose file name can be defined in a variable named `docker_compose_file`. - + Also, in the case where pytest is running from a docker container, this fixture makes sure our container will be attached to all the docker networks. """ @@ -463,9 +463,9 @@ def nginxproxy(): ############################################################################### -# +# # Py.test hooks -# +# ############################################################################### # pytest hook to display additionnal stuff in test report @@ -492,9 +492,9 @@ def pytest_runtest_setup(item): pytest.xfail(f"previous test failed ({previousfailed.name})") ############################################################################### -# +# # Check requirements -# +# ############################################################################### try: From b9ac4b936e15b482b1a9b4712a265ebf934b625d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jan 2022 04:21:32 +0000 Subject: [PATCH 13/71] chore(deps): bump requests from 2.26.0 to 2.27.1 in /test/requirements Bumps [requests](https://github.com/psf/requests) from 2.26.0 to 2.27.1. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.26.0...v2.27.1) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- test/requirements/python-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements/python-requirements.txt b/test/requirements/python-requirements.txt index 1a2ad1e..1e53b31 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -2,4 +2,4 @@ backoff==1.11.1 docker-compose==1.29.2 docker==5.0.3 pytest==6.2.5 -requests==2.26.0 +requests==2.27.1 From 53ef90a2f6e02b295c8e176c7cd08a139d958d54 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Thu, 6 Jan 2022 17:12:36 +0100 Subject: [PATCH 14/71] docs: nginx badge 1.21.4 -> 1.21.5 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45b0f6c..c5f153f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Test](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml/badge.svg)](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml) [![GitHub release](https://img.shields.io/github/v/release/nginx-proxy/nginx-proxy)](https://github.com/nginx-proxy/nginx-proxy/releases) -![nginx 1.21.4](https://img.shields.io/badge/nginx-1.21.4-brightgreen.svg) +![nginx 1.21.5](https://img.shields.io/badge/nginx-1.21.5-brightgreen.svg) [![Docker Image Size](https://img.shields.io/docker/image-size/nginxproxy/nginx-proxy?sort=semver)](https://hub.docker.com/r/nginxproxy/nginx-proxy "Click to view the image on Docker Hub") [![Docker stars](https://img.shields.io/docker/stars/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub') [![Docker pulls](https://img.shields.io/docker/pulls/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub') From 679c971a19d7d159f551e95aae654280934009bc Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 11 Jan 2022 19:46:42 +0100 Subject: [PATCH 15/71] docs: update maintainers list on license --- LICENSE | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index fc926a8..ce7d86c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) -Copyright (c) 2014 Jason Wilder +Copyright (c) 2014-2020 Jason Wilder +Copyright (c) 2021-2022 Nicolas Duchon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From fde0e809e4758d255be61f7207c8d538b82232bc Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 11 Jan 2022 19:55:29 +0100 Subject: [PATCH 16/71] chore: jwilder/docker-gen > nginx-proxy/docker-gen --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- README.md | 6 +++--- docker-compose-separate-containers.yml | 5 +++-- test/test_dockergen/test_dockergen_v2.yml | 2 +- test/test_dockergen/test_dockergen_v3.yml | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 95db046..22f910d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ FROM gobuilder as dockergen ARG DOCKER_GEN_VERSION -RUN git clone https://github.com/jwilder/docker-gen \ +RUN git clone https://github.com/nginx-proxy/docker-gen \ && cd /go/docker-gen \ && git -c advice.detachedHead=false checkout $DOCKER_GEN_VERSION \ && go mod download \ diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 81fd9d3..94a122e 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -11,7 +11,7 @@ FROM gobuilder as dockergen ARG DOCKER_GEN_VERSION -RUN git clone https://github.com/jwilder/docker-gen \ +RUN git clone https://github.com/nginx-proxy/docker-gen \ && cd /go/docker-gen \ && git -c advice.detachedHead=false checkout $DOCKER_GEN_VERSION \ && go mod download \ diff --git a/README.md b/README.md index c5f153f..18e5dcf 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ docker run -d -e VIRTUAL_HOST=foo.bar.com nginx ### Separate Containers -nginx-proxy can also be run as two separate containers using the [jwilder/docker-gen](https://hub.docker.com/r/jwilder/docker-gen) image and the official [nginx](https://registry.hub.docker.com/_/nginx/) image. +nginx-proxy can also be run as two separate containers using the [nginxproxy/docker-gen](https://hub.docker.com/r/nginxproxy/docker-gen) image and the official [nginx](https://registry.hub.docker.com/_/nginx/) image. You may want to do this to prevent having the docker socket bound to a publicly exposed container service. @@ -224,7 +224,7 @@ Then start the docker-gen container with the shared volume and template: docker run --volumes-from nginx \ -v /var/run/docker.sock:/tmp/docker.sock:ro \ -v $(pwd):/etc/docker-gen/templates \ - -t jwilder/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf + -t nginxproxy/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf ``` Finally, start your containers with `VIRTUAL_HOST` environment variables. @@ -259,7 +259,7 @@ To use custom `dhparam.pem` files per-virtual-host, the files should be named af > COMPATIBILITY WARNING: The default generated `dhparam.pem` key is 4096 bits for A+ security. Some older clients (like Java 6 and 7) do not support DH keys with over 1024 bits. In order to support these clients, you must provide your own `dhparam.pem`. -In the separate container setup, no pre-generated key will be available and neither the [jwilder/docker-gen](https://hub.docker.com/r/jwilder/docker-gen) image, nor the offical [nginx](https://registry.hub.docker.com/_/nginx/) image will provide one. If you still want A+ security in a separate container setup, you should mount an RFC7919 DH key file to the nginx container at `/etc/nginx/dhparam/dhparam.pem`. +In the separate container setup, no pre-generated key will be available and neither the [nginxproxy/docker-gen](https://hub.docker.com/r/nginxproxy/docker-gen) image, nor the offical [nginx](https://registry.hub.docker.com/_/nginx/) image will provide one. If you still want A+ security in a separate container setup, you should mount an RFC7919 DH key file to the nginx container at `/etc/nginx/dhparam/dhparam.pem`. Set `DHPARAM_SKIP` environment variable to `true` to disable using default Diffie-Hellman parameters. The default value is `false`. diff --git a/docker-compose-separate-containers.yml b/docker-compose-separate-containers.yml index a4edb94..254b742 100644 --- a/docker-compose-separate-containers.yml +++ b/docker-compose-separate-containers.yml @@ -9,8 +9,9 @@ services: - /etc/nginx/conf.d dockergen: - image: jwilder/docker-gen - command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf + image: nginxproxy/docker-gen + command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl + /etc/nginx/conf.d/default.conf volumes_from: - nginx volumes: diff --git a/test/test_dockergen/test_dockergen_v2.yml b/test/test_dockergen/test_dockergen_v2.yml index 919461d..b1f443c 100644 --- a/test/test_dockergen/test_dockergen_v2.yml +++ b/test/test_dockergen/test_dockergen_v2.yml @@ -8,7 +8,7 @@ services: - /etc/nginx/conf.d dockergen: - image: jwilder/docker-gen + image: nginxproxy/docker-gen command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf volumes_from: - nginx diff --git a/test/test_dockergen/test_dockergen_v3.yml b/test/test_dockergen/test_dockergen_v3.yml index 5bc4bff..8339273 100644 --- a/test/test_dockergen/test_dockergen_v3.yml +++ b/test/test_dockergen/test_dockergen_v3.yml @@ -7,7 +7,7 @@ services: - nginx_conf:/etc/nginx/conf.d dockergen: - image: jwilder/docker-gen + image: nginxproxy/docker-gen command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf volumes: - /var/run/docker.sock:/tmp/docker.sock:ro From fbf37456d02523bf9beeac9f498384de283b6258 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 11 Jan 2022 22:38:30 +0100 Subject: [PATCH 17/71] feat: display container version --- Dockerfile | 15 ++++++++------- Dockerfile.alpine | 15 ++++++++------- docker-entrypoint.sh | 8 ++++++++ nginx.tmpl | 5 +++++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Dockerfile b/Dockerfile index 22f910d..232098e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,6 +39,14 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ FROM nginx:1.21.5 LABEL maintainer="Nicolas Duchon (@buchdag)" +ARG NGINX_PROXY_VERSION +# Add DOCKER_GEN_VERSION environment variable +# Because some external projects rely on it +ARG DOCKER_GEN_VERSION +ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \ + DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \ + DOCKER_HOST=unix:///tmp/docker.sock + # Install wget and install/updates certificates RUN apt-get update \ && apt-get install -y -q --no-install-recommends \ @@ -58,17 +66,10 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen -# Add DOCKER_GEN_VERSION environment variable -# Because some external projects rely on it -ARG DOCKER_GEN_VERSION -ENV DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} - COPY network_internal.conf /etc/nginx/ COPY . /app/ WORKDIR /app/ -ENV DOCKER_HOST unix:///tmp/docker.sock - ENTRYPOINT ["/app/docker-entrypoint.sh"] CMD ["forego", "start", "-r"] diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 94a122e..6852b5a 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -40,6 +40,14 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ FROM nginx:1.21.5-alpine LABEL maintainer="Nicolas Duchon (@buchdag)" +ARG NGINX_PROXY_VERSION +# Add DOCKER_GEN_VERSION environment variable +# Because some external projects rely on it +ARG DOCKER_GEN_VERSION +ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \ + DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \ + DOCKER_HOST=unix:///tmp/docker.sock + # Install wget and install/updates certificates RUN apk add --no-cache --virtual .run-deps \ ca-certificates bash wget openssl \ @@ -55,17 +63,10 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen -# Add DOCKER_GEN_VERSION environment variable -# Because some external projects rely on it -ARG DOCKER_GEN_VERSION -ENV DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} - COPY network_internal.conf /etc/nginx/ COPY . /app/ WORKDIR /app/ -ENV DOCKER_HOST unix:///tmp/docker.sock - ENTRYPOINT ["/app/docker-entrypoint.sh"] CMD ["forego", "start", "-r"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 45d6cd2..8f4ed7a 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -29,6 +29,12 @@ function _parse_false() { esac } +function _print_version { + if [[ -n "${NGINX_PROXY_VERSION:-}" ]]; then + echo "Info: running nginx-proxy version ${NGINX_PROXY_VERSION}" + fi +} + function _check_unix_socket() { # Warn if the DOCKER_HOST socket does not exist if [[ ${DOCKER_HOST} == unix://* ]]; then @@ -96,6 +102,8 @@ function _setup_dhparam() { # Run the init logic if the default CMD was provided if [[ $* == 'forego start -r' ]]; then + _print_version + _check_unix_socket _resolvers diff --git a/nginx.tmpl b/nginx.tmpl index 2e1415e..2414633 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,5 +1,6 @@ {{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }} +{{ $nginx_proxy_version := coalesce $.Env.NGINX_PROXY_VERSION "" }} {{ $external_http_port := coalesce $.Env.HTTP_PORT "80" }} {{ $external_https_port := coalesce $.Env.HTTPS_PORT "443" }} {{ $debug_all := $.Env.DEBUG }} @@ -48,6 +49,10 @@ {{ end }} {{ end }} +{{ if ne $nginx_proxy_version "" }} +# nginx-proxy version : {{ $nginx_proxy_version }} +{{ end }} + # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { From e22ae4a6fdfa6760651b9864a3fb042ba896a9ff Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 11 Jan 2022 22:53:39 +0100 Subject: [PATCH 18/71] tests: display container version --- Makefile | 4 ++-- test/test_nominal.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 18fcd33..ab44880 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,10 @@ build-webserver: docker build -t web test/requirements/web build-nginx-proxy-test-debian: - docker build -t nginxproxy/nginx-proxy:test . + docker build --build-arg NGINX_PROXY_VERSION="test" -t nginxproxy/nginx-proxy:test . build-nginx-proxy-test-alpine: - docker build -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test . + docker build --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test . test-debian: build-webserver build-nginx-proxy-test-debian test/pytest.sh diff --git a/test/test_nominal.py b/test/test_nominal.py index cce7c94..a3f9c87 100644 --- a/test/test_nominal.py +++ b/test/test_nominal.py @@ -22,3 +22,8 @@ def test_forwards_to_web2(docker_compose, nginxproxy): def test_ipv6_is_disabled_by_default(docker_compose, nginxproxy): with pytest.raises(ConnectionError): nginxproxy.get("http://nginx-proxy/port", ipv6=True) + + +def test_container_version_is_displayed(docker_compose, nginxproxy): + conf = nginxproxy.get_conf().decode('ASCII') + assert "# nginx-proxy version : test" in conf From dbca945a8f1f1dbd35f0f8308413a1859882660a Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Wed, 12 Jan 2022 11:26:20 +0100 Subject: [PATCH 19/71] ci: add nginx-proxy version to image on build --- .github/workflows/dockerhub.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 5d4cfba..3dea999 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -53,12 +53,16 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Retrieve version + run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV + - name: Build and push the Debian based image id: docker_build_debian uses: docker/build-push-action@v2 with: context: . file: Dockerfile + build-args: NGINX_PROXY_VERSION=${{ env.GIT_DESCRIBE }} platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: ${{ steps.docker_meta_debian.outputs.tags }} @@ -101,12 +105,16 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Retrieve version + run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV + - name: Build and push the Alpine based image id: docker_build_alpine uses: docker/build-push-action@v2 with: context: . file: Dockerfile.alpine + build-args: NGINX_PROXY_VERSION=${{ env.GIT_DESCRIBE }} platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: ${{ steps.docker_meta_alpine.outputs.tags }} From b411a84a59d138e5dd1ce87ca85203c082f98461 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 14 Jan 2022 13:38:23 +0100 Subject: [PATCH 20/71] docs: update issue template --- .github/ISSUE_TEMPLATE.md | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 99d688b..9824d63 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,16 +1,35 @@ -# !!!PLEASE READ!!! +# ⚠️ PLEASE READ ⚠️ -## Questions +## Questions or Features -If you have a question, DO NOT SUBMIT a new issue. +If you have a question or want to request a feature, please **DO NOT SUBMIT** a new issue. -Please ask the question on the Discussions section: https://github.com/nginx-proxy/nginx-proxy/discussions +Instead please use the relevant Discussions section's category: +- 🙏 [Ask a question](https://github.com/nginx-proxy/nginx-proxy/discussions/categories/q-a) +- 💡 [Request a feature](https://github.com/nginx-proxy/nginx-proxy/discussions/categories/ideas) -## Bugs or Features +## Bugs -If you are logging a bug or feature request, please search the current open issues to see if there is already a bug or feature opened. +If you are logging a bug, please search the current open issues first to see if there is already a bug opened. -For bugs, the easier you make it to reproduce the issue you see, the easier and faster it can get fixed. If you can provide a script or docker-compose file that reproduces the problems, that is very helpful. +For bugs, the easier you make it to reproduce the issue you see and the more initial information you provide, the easier and faster the bug can be identified and can get fixed. + +Please at least provide: +- the exact nginx-proxy version you're using (if using `latest` please make sure it is up to date and provide the version number printed at container startup). +- complete configuration (compose file, command line, etc) of both your nginx-proxy container(s) and proxied containers. You should redact sensitive info if needed but please provide **full** configurations. +- generated nginx configuration obtained with `docker exec nameofyournginxproxycontainer nginx -T` + +If you can provide a script or docker-compose file that reproduces the problems, that is very helpful. + +## General advice about `latest` + +Do not use the `latest` tag for production setups. + +`latest` is nothing more than a convenient default used by Docker if no specific tag is provided, there isn't any strict convention on what goes into this tag over different projects, and it does not carry any promise of stability. + +Using `latest` will most certainly put you at risk of experiencing uncontrolled updates to non backward compatible versions (or versions with breaking changes) and makes it harder for maintainers to track which exact version of the container you are experiencing an issue with. + +This recommendation stands for pretty much every Docker image in existence, not just nginx-proxy's ones. Thanks, -Jason +Nicolas From 2daa09ff21be7970631ad3b709ab823b47d68337 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 14 Jan 2022 14:17:21 +0100 Subject: [PATCH 21/71] ci: upgrade to docker/metadata-action@v3 --- .github/workflows/dockerhub.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 3dea999..c39d457 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -31,7 +31,7 @@ jobs: - name: Get Docker tags for Debian based image id: docker_meta_debian - uses: crazy-max/ghaction-docker-meta@v2 + uses: docker/metadata-action@v3 with: images: | nginxproxy/nginx-proxy @@ -82,7 +82,7 @@ jobs: - name: Get Docker tags for Alpine based image id: docker_meta_alpine - uses: crazy-max/ghaction-docker-meta@v2 + uses: docker/metadata-action@v3 with: images: | nginxproxy/nginx-proxy From 0ff39b804cc2f98816a78ee95ab5e5229ed2894d Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 14 Jan 2022 14:29:03 +0100 Subject: [PATCH 22/71] ci: use git describe for OCI image version label --- .github/workflows/dockerhub.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index c39d457..757e8ac 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -28,6 +28,9 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 + + - name: Retrieve version + run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV - name: Get Docker tags for Debian based image id: docker_meta_debian @@ -40,6 +43,8 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + labels: | + org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} - name: Set up QEMU uses: docker/setup-qemu-action@v1 @@ -53,9 +58,6 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Retrieve version - run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV - - name: Build and push the Debian based image id: docker_build_debian uses: docker/build-push-action@v2 @@ -79,6 +81,9 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 + + - name: Retrieve version + run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV - name: Get Docker tags for Alpine based image id: docker_meta_alpine @@ -91,6 +96,8 @@ jobs: type=semver,suffix=-alpine,pattern={{version}} type=semver,suffix=-alpine,pattern={{major}}.{{minor}} type=raw,value=alpine,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + labels: | + org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} flavor: latest=false - name: Set up QEMU @@ -105,9 +112,6 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Retrieve version - run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV - - name: Build and push the Alpine based image id: docker_build_alpine uses: docker/build-push-action@v2 From 42c8b0c4c9e31889d6c1f66397ac004d1965e095 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 14 Jan 2022 14:39:33 +0100 Subject: [PATCH 23/71] CI: replace maintainer label w/ OCI authors label --- .github/workflows/dockerhub.yml | 2 ++ Dockerfile | 1 - Dockerfile.alpine | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 757e8ac..cb3635e 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -44,6 +44,7 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} labels: | + org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} - name: Set up QEMU @@ -97,6 +98,7 @@ jobs: type=semver,suffix=-alpine,pattern={{major}}.{{minor}} type=raw,value=alpine,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} labels: | + org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} flavor: latest=false diff --git a/Dockerfile b/Dockerfile index 232098e..4574b27 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,7 +37,6 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ # Build the final image FROM nginx:1.21.5 -LABEL maintainer="Nicolas Duchon (@buchdag)" ARG NGINX_PROXY_VERSION # Add DOCKER_GEN_VERSION environment variable diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 6852b5a..c7f2472 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -38,7 +38,6 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ # Build the final image FROM nginx:1.21.5-alpine -LABEL maintainer="Nicolas Duchon (@buchdag)" ARG NGINX_PROXY_VERSION # Add DOCKER_GEN_VERSION environment variable From 2671ef4aef0b28355ca555ca02096819fb69864c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jan 2022 04:07:38 +0000 Subject: [PATCH 24/71] chore(deps): bump nginx from 1.21.5 to 1.21.6 Bumps nginx from 1.21.5 to 1.21.6. --- updated-dependencies: - dependency-name: nginx dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4574b27..d5c71bc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ && rm -rf /go/forego # Build the final image -FROM nginx:1.21.5 +FROM nginx:1.21.6 ARG NGINX_PROXY_VERSION # Add DOCKER_GEN_VERSION environment variable diff --git a/Dockerfile.alpine b/Dockerfile.alpine index c7f2472..2552615 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -37,7 +37,7 @@ RUN git clone https://github.com/nginx-proxy/forego/ \ && rm -rf /go/forego # Build the final image -FROM nginx:1.21.5-alpine +FROM nginx:1.21.6-alpine ARG NGINX_PROXY_VERSION # Add DOCKER_GEN_VERSION environment variable From dc8094daf57ad1fe313c18d1adaca0ad855c9984 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Feb 2022 04:23:26 +0000 Subject: [PATCH 25/71] chore(deps): bump pytest from 6.2.5 to 7.0.0 in /test/requirements Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.5 to 7.0.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.5...7.0.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- test/requirements/python-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements/python-requirements.txt b/test/requirements/python-requirements.txt index 1e53b31..be4665e 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -1,5 +1,5 @@ backoff==1.11.1 docker-compose==1.29.2 docker==5.0.3 -pytest==6.2.5 +pytest==7.0.0 requests==2.27.1 From 42535c01d97a3d8d255c9e8f90b9b2d78e6d596f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Feb 2022 04:20:00 +0000 Subject: [PATCH 26/71] chore(deps): bump pytest from 7.0.0 to 7.0.1 in /test/requirements Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.0.0...7.0.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- test/requirements/python-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements/python-requirements.txt b/test/requirements/python-requirements.txt index be4665e..3747455 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -1,5 +1,5 @@ backoff==1.11.1 docker-compose==1.29.2 docker==5.0.3 -pytest==7.0.0 +pytest==7.0.1 requests==2.27.1 From 098e551c3522c5493b663feb26c33dd83248a453 Mon Sep 17 00:00:00 2001 From: Nathan Weeks <1800812+nathanweeks@users.noreply.github.com> Date: Mon, 14 Feb 2022 07:42:46 -0500 Subject: [PATCH 27/71] Fix path to default.conf in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 18e5dcf..e996eed 100644 --- a/README.md +++ b/README.md @@ -423,10 +423,10 @@ Please note that using regular expressions in `VIRTUAL_HOST` will always result ### 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`: +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.conf`: ```console -docker exec cat /etc/nginx/conf.d/default +docker exec cat /etc/nginx/conf.d/default.conf ``` Especially at `upstream` definition blocks which should look like: From 15e33a3de57f59cef8c883120b24d7dde695fca8 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 14 Feb 2022 16:18:25 +0100 Subject: [PATCH 28/71] docs: suggest alternatives to xip.io Fixes #1887 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 18e5dcf..d955a33 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrie ### 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). +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 [nip.io](https://nip.io) or [sslip.io](https://sslip.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). ### Multiple Networks From 3670d39b71e8fe7dcc0b317accdf1d9ba6f18840 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 15 Feb 2022 11:12:52 +0100 Subject: [PATCH 29/71] docs: xip.io -> nip.io --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c175ad2..556cf5c 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrie ### 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 [nip.io](https://nip.io) or [sslip.io](https://sslip.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). +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 [nip.io](https://nip.io) or [sslip.io](https://sslip.io), using `~^foo\.bar\..*\.nip\.io` will match `foo.bar.127.0.0.1.nip.io`, `foo.bar.10.0.2.2.nip.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). ### Multiple Networks From 18027fa71b0c28312b2c290f99a74fbbac03ad76 Mon Sep 17 00:00:00 2001 From: Robin Windey Date: Sun, 20 Feb 2022 15:10:05 +0100 Subject: [PATCH 30/71] Add container logs in case testcontainer exited unexpectedly --- test/conftest.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/conftest.py b/test/conftest.py index cf26b30..1121e96 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -192,6 +192,10 @@ def nginx_proxy_dns_resolver(domain_name): nginxproxy_containers = docker_client.containers.list(filters={"status": "running", "ancestor": "nginxproxy/nginx-proxy:test"}) if len(nginxproxy_containers) == 0: log.warn(f"no container found from image nginxproxy/nginx-proxy:test while resolving {domain_name!r}") + exited_nginxproxy_containers = docker_client.containers.list(filters={"status": "exited", "ancestor": "nginxproxy/nginx-proxy:test"}) + if len(exited_nginxproxy_containers) > 0: + exited_nginxproxy_container_logs = exited_nginxproxy_containers[0].logs() + log.warn(f"nginxproxy/nginx-proxy:test container might have exited unexpectedly. Container logs: " + "\n" + exited_nginxproxy_container_logs.decode()) return nginxproxy_container = nginxproxy_containers[0] ip = container_ip(nginxproxy_container) From b6e9cdc065a19ce7e7cb0dcf2c11cd7c9fe1d063 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 4 May 2021 11:03:27 +0200 Subject: [PATCH 31/71] ci: use docker-gen main on dev branch tests --- .github/workflows/test.yml | 20 ++++++++++++++++---- Makefile | 6 ++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6be93bd..8c4a173 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,13 +3,16 @@ name: Tests on: workflow_dispatch: push: + branches: + - main + - dev paths-ignore: - - 'LICENSE' - - '**.md' + - 'LICENSE' + - '**.md' pull_request: paths-ignore: - - 'LICENSE' - - '**.md' + - 'LICENSE' + - '**.md' jobs: unit: @@ -39,6 +42,15 @@ jobs: - name: Build Docker nginx proxy test image run: make build-nginx-proxy-test-${{ matrix.base_docker_image }} + if: | + ( github.event_name == 'push' && github.ref != 'refs/heads/dev' ) || + ( github.event_name == 'pull_request' && github.base_ref != 'dev' ) + + - name: Build Docker nginx proxy dev test image + run: make build-nginx-proxy-test-${{ matrix.base_docker_image }}-dev + if: | + ( github.event_name == 'push' && github.ref == 'refs/heads/dev' ) || + ( github.event_name == 'pull_request' && github.base_ref == 'dev' ) - name: Run tests run: pytest diff --git a/Makefile b/Makefile index ab44880..60406b6 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,12 @@ build-nginx-proxy-test-debian: build-nginx-proxy-test-alpine: docker build --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test . +build-nginx-proxy-test-debian-dev: + docker build --build-arg DOCKER_GEN_VERSION=main -t nginxproxy/nginx-proxy:test . + +build-nginx-proxy-test-alpine-dev: + docker build -f Dockerfile.alpine --build-arg DOCKER_GEN_VERSION=main -t nginxproxy/nginx-proxy:test . + test-debian: build-webserver build-nginx-proxy-test-debian test/pytest.sh From 2901b917a0cee641b58e66338d8855366b60d1c2 Mon Sep 17 00:00:00 2001 From: Greg Symons Date: Sun, 23 May 2021 22:52:57 +0200 Subject: [PATCH 32/71] feat: support for path-based routing Co-authored-by: Josh Trow Co-authored-by: Adrian Co-authored-by: Rodrigo Aguilera Co-authored-by: Alexander Lieret --- nginx.tmpl | 212 +++++++++++++++++++++++++++++------------------------ 1 file changed, 115 insertions(+), 97 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 2414633..fc6f540 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -49,6 +49,92 @@ {{ end }} {{ end }} +{{ define "location" }} +location {{ .Path }} { + {{ if eq .Proto "uwsgi" }} + include uwsgi_params; + uwsgi_pass {{ trim .Proto }}://{{ trim .Upstream }}; + {{ else if eq .Proto "fastcgi" }} + root {{ trim .Vhostroot }}; + include fastcgi.conf; + fastcgi_pass {{ trim .Upstream }}; + {{ else if eq .Proto "grpc" }} + grpc_pass {{ trim .Proto }}://{{ trim .Upstream }}; + {{ else }} + proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}/; + {{ end }} + + {{ if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }} + auth_basic "Restricted {{ .Host }}"; + auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" .Host) }}; + {{ end }} + + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}}; + {{ else if (exists "/etc/nginx/vhost.d/default_location") }} + include /etc/nginx/vhost.d/default_location; + {{ end }} +} +{{ end }} + +{{ define "upstream-definition" }} + {{ $networks := .Networks }} + {{ $debug_all := .Debug }} + upstream {{ .Upstream }} { + {{ $server_found := "false" }} + {{ range $container := .Containers }} + {{ $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 }} + {{ $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 }} + {{ range $knownNetwork := $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 $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 }} + {{ $server_found = "true" }} + # {{ $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 $containerNetwork }} + {{ $server_found = "true" }} + # {{ $container.Name }} + server {{ $containerNetwork.IP }}:{{ $address.Port }}; + {{ end }} + {{ else if $containerNetwork }} + # {{ $container.Name }} + {{ if $containerNetwork.IP }} + {{ $server_found = "true" }} + server {{ $containerNetwork.IP }}:{{ $port }}; + {{ else }} + # /!\ No IP for this network! + {{ end }} + {{ end }} + {{ else }} + # Cannot connect to network '{{ $containerNetwork.Name }}' of this container + {{ end }} + {{ end }} + {{ end }} + {{ end }} + {{/* nginx-proxy/nginx-proxy#1105 */}} + {{ if (eq $server_found "false") }} + # Fallback entry + server 127.0.0.1 down; + {{ end }} + } +{{ end }} + {{ if ne $nginx_proxy_version "" }} # nginx-proxy version : {{ $nginx_proxy_version }} {{ end }} @@ -100,6 +186,7 @@ access_log off; {{/* Get the SSL_POLICY defined by this container, falling back to "Mozilla-Intermediate" */}} {{ $ssl_policy := or ($.Env.SSL_POLICY) "Mozilla-Intermediate" }} {{ template "ssl_policy" (dict "ssl_policy" $ssl_policy) }} +error_log /dev/stderr; {{ if $.Env.RESOLVERS }} resolver {{ $.Env.RESOLVERS }}; @@ -119,6 +206,7 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; +proxy_set_header X-Original-URI $request_uri; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; @@ -162,61 +250,20 @@ server { {{ $is_regexp := hasPrefix "~" $host }} {{ $upstream_name := when (or $is_regexp $sha1_upstream_name) (sha1 $host) $host }} -# {{ $host }} -upstream {{ $upstream_name }} { +{{ $paths := groupBy $containers "Env.VIRTUAL_PATH" }} +{{ $nPaths := len $paths }} -{{ $server_found := "false" }} -{{ range $container := $containers }} - {{ $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 }} - {{ $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 }} - {{ 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 $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 }} - {{ $server_found = "true" }} - # {{ $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 $containerNetwork }} - {{ $server_found = "true" }} - # {{ $container.Name }} - server {{ $containerNetwork.IP }}:{{ $address.Port }}; - {{ end }} - {{ else if $containerNetwork }} - # {{ $container.Name }} - {{ if $containerNetwork.IP }} - {{ $server_found = "true" }} - server {{ $containerNetwork.IP }}:{{ $port }}; - {{ else }} - # /!\ No IP for this network! - {{ end }} - {{ end }} - {{ else }} - # Cannot connect to network '{{ $containerNetwork.Name }}' of this container - {{ end }} - {{ end }} +{{ if eq $nPaths 0 }} + # {{ $host }} + {{ template "upstream-definition" (dict "Upstream" $upstream_name "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }} +{{ else }} + {{ range $path, $containers := $paths }} + {{ $sum := sha1 $path }} + {{ $upstream := printf "%s-%s" $upstream_name $sum }} + # {{ $host }}{{ $path }} + {{ template "upstream-definition" (dict "Upstream" $upstream "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }} {{ end }} {{ end }} -{{/* nginx-proxy/nginx-proxy#1105 */}} -{{ if (eq $server_found "false") }} - # Fallback entry - server 127.0.0.1 down; -{{ end }} -} {{ $default_host := or ($.Env.DEFAULT_HOST) "" }} {{ $default_server := index (dict $host "" $default_host "default_server") $host }} @@ -337,30 +384,15 @@ server { include /etc/nginx/vhost.d/default; {{ end }} - location / { - {{ if eq $proto "uwsgi" }} - include uwsgi_params; - uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ else if eq $proto "fastcgi" }} - root {{ trim $vhost_root }}; - include fastcgi_params; - fastcgi_pass {{ trim $upstream_name }}; - {{ else if eq $proto "grpc" }} - grpc_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ else }} - proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; + {{ if eq $nPaths 0 }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root) }} + {{ else }} + {{ range $path, $container := $paths }} + {{ $sum := sha1 $path }} + {{ $upstream := printf "%s-%s" $host $sum }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root) }} {{ end }} - - {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} - auth_basic "Restricted {{ $host }}"; - auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; - {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/nginx/vhost.d/default_location") }} - include /etc/nginx/vhost.d/default_location; - {{ end }} - } + {{ end }} } {{ end }} @@ -389,29 +421,15 @@ server { include /etc/nginx/vhost.d/default; {{ end }} - location / { - {{ if eq $proto "uwsgi" }} - include uwsgi_params; - uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ else if eq $proto "fastcgi" }} - root {{ trim $vhost_root }}; - include fastcgi_params; - fastcgi_pass {{ trim $upstream_name }}; - {{ else if eq $proto "grpc" }} - grpc_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ else }} - proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; + {{ if eq $nPaths 0 }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root) }} + {{ else }} + {{ range $path, $container := $paths }} + {{ $sum := sha1 $path }} + {{ $upstream := printf "%s-%s" $upstream_name $sum }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root) }} {{ end }} - {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} - auth_basic "Restricted {{ $host }}"; - auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; - {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/nginx/vhost.d/default_location") }} - include /etc/nginx/vhost.d/default_location; - {{ end }} - } + {{ end }} } {{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} From fc4c4e17cab24f84f6b2b9691a43cd4bb90d688b Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 6 Jul 2021 14:40:21 +0200 Subject: [PATCH 33/71] ci: Add tests for the virtual-path routing @gregsymons test cases were too outdated to be ported easily. The new tests should include the coverage of the old ones. --- test/test_events.py | 38 +++++++++++- test/test_virtual-path/test_virtual_paths.py | 59 +++++++++++++++++++ test/test_virtual-path/test_virtual_paths.yml | 42 +++++++++++++ 3 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 test/test_virtual-path/test_virtual_paths.py create mode 100644 test/test_virtual-path/test_virtual_paths.yml diff --git a/test/test_events.py b/test/test_events.py index 201917f..b5da3dd 100644 --- a/test/test_events.py +++ b/test/test_events.py @@ -29,13 +29,36 @@ def web1(docker_compose): except NotFound: pass +@pytest.fixture() +def web2(docker_compose): + """ + pytest fixture creating a web container with `VIRTUAL_HOST=nginx-proxy`, `VIRTUAL_PATH=/web2/` and `VIRTUAL_DEST=/` listening on port 82. + """ + container = docker_compose.containers.run( + name="web2", + image="web", + detach=True, + environment={ + "WEB_PORTS": "82", + "VIRTUAL_HOST": "nginx-proxy", + "VIRTUAL_PATH": "/web2/", + "VIRTUAL_DEST": "/", + }, + ports={"82/tcp": None} + ) + sleep(2) # give it some time to initialize and for docker-gen to detect it + yield container + try: + docker_compose.containers.get("web2").remove(force=True) + except NotFound: + pass def test_nginx_proxy_behavior_when_alone(docker_compose, nginxproxy): r = nginxproxy.get("http://nginx-proxy/") assert r.status_code == 503 -def test_new_container_is_detected(web1, nginxproxy): +def test_new_container_is_detected_vhost(web1, nginxproxy): r = nginxproxy.get("http://web1.nginx-proxy/port") assert r.status_code == 200 assert "answer from port 81\n" == r.text @@ -44,3 +67,16 @@ def test_new_container_is_detected(web1, nginxproxy): sleep(2) r = nginxproxy.get("http://web1.nginx-proxy/port") assert r.status_code == 503 + +def test_new_container_is_detected_vpath(web2, nginxproxy): + r = nginxproxy.get("http://nginx-proxy/web2/port") + assert r.status_code == 200 + assert "answer from port 82\n" == r.text + r = nginxproxy.get("http://nginx-proxy/port") + assert r.status_code in [404, 503] + + web2.remove(force=True) + sleep(2) + r = nginxproxy.get("http://nginx-proxy/web2/port") + assert r.status_code == 503 + diff --git a/test/test_virtual-path/test_virtual_paths.py b/test/test_virtual-path/test_virtual_paths.py new file mode 100644 index 0000000..115d47f --- /dev/null +++ b/test/test_virtual-path/test_virtual_paths.py @@ -0,0 +1,59 @@ +from time import sleep + +import pytest +from docker.errors import NotFound + +@pytest.mark.parametrize("stub,expected_port", [ + ("nginx-proxy.test/web1", 81), + ("nginx-proxy.test/web2", 82), + ("nginx-proxy.test", 83), + ("foo.nginx-proxy.test", 42), +]) +def test_valid_path(docker_compose, nginxproxy, stub, expected_port): + r = nginxproxy.get(f"http://{stub}/port") + assert r.status_code == 200 + assert r.text == f"answer from port {expected_port}\n" + +@pytest.mark.parametrize("stub", [ + "nginx-proxy.test/foo", + "bar.nginx-proxy.test", +]) +def test_invalid_path(docker_compose, nginxproxy, stub): + r = nginxproxy.get(f"http://{stub}/port") + assert r.status_code in [404, 503] + +@pytest.fixture() +def web4(docker_compose): + """ + pytest fixture creating a web container with `VIRTUAL_HOST=nginx-proxy.test`, `VIRTUAL_PATH=/web4/` and `VIRTUAL_DEST=/` listening on port 84. + """ + container = docker_compose.containers.run( + name="web4", + image="web", + detach=True, + environment={ + "WEB_PORTS": "84", + "VIRTUAL_HOST": "nginx-proxy.test", + "VIRTUAL_PATH": "/web4/", + "VIRTUAL_DEST": "/", + }, + ports={"84/tcp": None} + ) + sleep(2) # give it some time to initialize and for docker-gen to detect it + yield container + try: + docker_compose.containers.get("web4").remove(force=True) + except NotFound: + pass + +""" +Test if we can add and remove a single virtual_path from multiple ones on the same subdomain. +""" +def test_container_hotplug(web4, nginxproxy): + r = nginxproxy.get(f"http://nginx-proxy.test/web4/port") + assert r.status_code == 200 + assert r.text == f"answer from port 84\n" + web4.remove(force=True) + sleep(2) + r = nginxproxy.get(f"http://nginx-proxy.test/web4/port") + assert r.status_code == 404 diff --git a/test/test_virtual-path/test_virtual_paths.yml b/test/test_virtual-path/test_virtual_paths.yml new file mode 100644 index 0000000..ca688eb --- /dev/null +++ b/test/test_virtual-path/test_virtual_paths.yml @@ -0,0 +1,42 @@ + +foo: + image: web + expose: + - "42" + environment: + WEB_PORTS: "42" + VIRTUAL_HOST: "foo.nginx-proxy.test" + +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/web1/" + +web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/web2/" + +web3: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/" + +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 + From e0e1732842b7c4f90847a4a9f7ca1747a8e17558 Mon Sep 17 00:00:00 2001 From: Greg Symons Date: Tue, 6 Jul 2021 15:02:09 +0200 Subject: [PATCH 34/71] docs: Add documentation for path-based routing Co-authored-by: Josh Trow Co-authored-by: Adrian Co-authored-by: Rodrigo Aguilera Co-authored-by: Alexander Lieret --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 556cf5c..9e248fa 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,12 @@ For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrie 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 [nip.io](https://nip.io) or [sslip.io](https://sslip.io), using `~^foo\.bar\..*\.nip\.io` will match `foo.bar.127.0.0.1.nip.io`, `foo.bar.10.0.2.2.nip.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). +### Path-based Routing + +You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, make give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`. + +The full request URI will be forwarded to the serving container in the `X-Forwarded-Path` header. + ### Multiple Networks With the addition of [overlay networking](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) in Docker 1.9, your `nginx-proxy` container may need to connect to backend containers on multiple networks. By default, if you don't pass the `--net` flag when your `nginx-proxy` container is created, it will only be attached to the default `bridge` network. This means that it will not be able to connect to containers on networks other than `bridge`. @@ -337,6 +343,7 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; +proxy_set_header X-Forwarded-Path $request_uri; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; From 9cd85f61d5165f5307cae1dfad5c165bc9821c75 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Thu, 15 Jul 2021 21:47:03 +0200 Subject: [PATCH 35/71] build: build and push the dev branch to Dockerhub --- .github/workflows/dockerhub.yml | 43 +++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index cb3635e..74283b7 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -7,6 +7,7 @@ on: push: branches: - main + - dev tags: - '*.*.*' paths-ignore: @@ -42,7 +43,8 @@ jobs: tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} + type=raw,value=dev,enable=${{ github.ref == 'refs/heads/dev' }} labels: | org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} @@ -60,6 +62,7 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push the Debian based image + if: github.ref == 'refs/heads/main' id: docker_build_debian uses: docker/build-push-action@v2 with: @@ -72,8 +75,25 @@ jobs: labels: ${{ steps.docker_meta_debian.outputs.labels }} - name: Images digests + if: github.ref == 'refs/heads/main' run: echo ${{ steps.docker_build_debian.outputs.digest }} + - name: Build and push the Debian based dev image + if: github.ref == 'refs/heads/dev' + id: docker_build_debian_dev + uses: docker/build-push-action@v2 + with: + file: Dockerfile + build-args: DOCKER_GEN_VERSION=main + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: true + tags: ${{ steps.docker_meta_debian.outputs.tags }} + labels: ${{ steps.docker_meta_debian.outputs.labels }} + + - name: Images digests + if: github.ref == 'refs/heads/dev' + run: echo ${{ steps.docker_build_debian_dev.outputs.digest }} + multiarch-build-alpine: runs-on: ubuntu-latest steps: @@ -96,7 +116,8 @@ jobs: tags: | type=semver,suffix=-alpine,pattern={{version}} type=semver,suffix=-alpine,pattern={{major}}.{{minor}} - type=raw,value=alpine,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=raw,value=alpine,enable=${{ github.ref == 'refs/heads/main' }} + type=raw,value=dev-alpine,enable=${{ github.ref == 'refs/heads/dev' }} labels: | org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} @@ -115,6 +136,7 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push the Alpine based image + if: github.ref == 'refs/heads/main' id: docker_build_alpine uses: docker/build-push-action@v2 with: @@ -127,4 +149,21 @@ jobs: labels: ${{ steps.docker_meta_alpine.outputs.labels }} - name: Images digests + if: github.ref == 'refs/heads/main' run: echo ${{ steps.docker_build_alpine.outputs.digest }} + + - name: Build and push the Alpine based dev image + if: github.ref == 'refs/heads/dev' + id: docker_build_alpine_dev + uses: docker/build-push-action@v2 + with: + file: Dockerfile.alpine + build-args: DOCKER_GEN_VERSION=main + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: true + tags: ${{ steps.docker_meta_alpine.outputs.tags }} + labels: ${{ steps.docker_meta_alpine.outputs.labels }} + + - name: Images digests + if: github.ref == 'refs/heads/dev' + run: echo ${{ steps.docker_build_alpine_dev.outputs.digest }} From dad4a2d7bfcf71d517b35a4fe1f7f46c74b4fea8 Mon Sep 17 00:00:00 2001 From: Rafael Kraut Date: Tue, 20 Jul 2021 10:28:39 +0200 Subject: [PATCH 36/71] docs: remove unnecessary word --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e248fa..262147c 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ You can also use wildcards at the beginning and the end of host name, like `*.ba ### Path-based Routing -You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, make give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`. +You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`. The full request URI will be forwarded to the serving container in the `X-Forwarded-Path` header. From 28c73e5b52d281964812e411c0a411dabf1a387e Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Wed, 11 Aug 2021 18:04:53 +0200 Subject: [PATCH 37/71] fix: non working https with virtual path --- nginx.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index fc6f540..73fba26 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -389,7 +389,7 @@ server { {{ else }} {{ range $path, $container := $paths }} {{ $sum := sha1 $path }} - {{ $upstream := printf "%s-%s" $host $sum }} + {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root) }} {{ end }} {{ end }} From 9df330e51ebb405966c942a4f5241faec16a462e Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 6 Jul 2021 15:26:02 +0200 Subject: [PATCH 38/71] feat: Add user customizable default root response --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- README.md | 10 +++++++++ nginx.tmpl | 11 ++++++++++ test/test_virtual-path/test_custom_conf.py | 6 ++++++ test/test_virtual-path/test_custom_conf.yml | 24 +++++++++++++++++++++ 6 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 test/test_virtual-path/test_custom_conf.py create mode 100644 test/test_virtual-path/test_custom_conf.yml diff --git a/Dockerfile b/Dockerfile index d5c71bc..bc4093d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=0.7.7 +ARG DOCKER_GEN_VERSION=main ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 2552615..98e9bc5 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,5 +1,5 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=0.7.7 +ARG DOCKER_GEN_VERSION=main ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries diff --git a/README.md b/README.md index 262147c..aa1b79b 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,16 @@ You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a The full request URI will be forwarded to the serving container in the `X-Forwarded-Path` header. +**NOTE**: Your application needs to be able to generate links starting with `VIRTUAL_PATH`. This can be achieved by it being natively on this path or havin an option to prepend this path. The application does not need to expect this path in the request. + +#### DEFAULT_ROOT + +This environment variable of the nginx proxy container can be used to customize the return error page if no matching path is found. Furthermore it is possible to use anything which is compatible with the `return` statement of nginx. + +For example `DEFAUL_ROOT=418` will return a 418 error page instead of the normal 404 one. +Another example is `DEFAULT_ROOT="301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` which would redirect an invalid request to this documentation. + + ### Multiple Networks With the addition of [overlay networking](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) in Docker 1.9, your `nginx-proxy` container may need to connect to backend containers on multiple networks. By default, if you don't pass the `--net` flag when your `nginx-proxy` container is created, it will only be attached to the default `bridge` network. This means that it will not be able to connect to containers on networks other than `bridge`. diff --git a/nginx.tmpl b/nginx.tmpl index 73fba26..85ccbda 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -5,6 +5,7 @@ {{ $external_https_port := coalesce $.Env.HTTPS_PORT "443" }} {{ $debug_all := $.Env.DEBUG }} {{ $sha1_upstream_name := parseBool (coalesce $.Env.SHA1_UPSTREAM_NAME "false") }} +{{ $default_root_response := coalesce $.Env.DEFAULT_ROOT "404" }} {{ define "ssl_policy" }} {{ if eq .ssl_policy "Mozilla-Modern" }} @@ -392,6 +393,11 @@ server { {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root) }} {{ end }} + {{ if (not (contains $paths "/")) }} + location / { + return {{ $default_root_response }}; + } + {{ end }} {{ end }} } @@ -429,6 +435,11 @@ server { {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root) }} {{ end }} + {{ if (not (contains $paths "/")) }} + location / { + return {{ $default_root_response }}; + } + {{ end }} {{ end }} } diff --git a/test/test_virtual-path/test_custom_conf.py b/test/test_virtual-path/test_custom_conf.py new file mode 100644 index 0000000..68ecd3a --- /dev/null +++ b/test/test_virtual-path/test_custom_conf.py @@ -0,0 +1,6 @@ +import pytest + +def test_default_root_response(docker_compose, nginxproxy): + r = nginxproxy.get("http://nginx-proxy.test/") + assert r.status_code == 418 + diff --git a/test/test_virtual-path/test_custom_conf.yml b/test/test_virtual-path/test_custom_conf.yml new file mode 100644 index 0000000..2fffd65 --- /dev/null +++ b/test/test_virtual-path/test_custom_conf.yml @@ -0,0 +1,24 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/web1/" + +web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/web2/" +sut: + image: nginxproxy/nginx-proxy:test + environment: + DEFAULT_ROOT: 418 + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro From 4b85e9582450ff07dcf205ad8ab5f5b1131599ef Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 6 Jul 2021 15:36:06 +0200 Subject: [PATCH 39/71] feat: Replace path stripping with variable This commit removes the automatic path stripping and replaces it with a user configurable environment variable. This can be set individually for each container. --- README.md | 14 ++++++++++++++ nginx.tmpl | 12 +++++++----- test/test_virtual-path/test_custom_conf.yml | 3 +++ test/test_virtual-path/test_virtual_paths.yml | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index aa1b79b..33ec073 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,20 @@ The full request URI will be forwarded to the serving container in the `X-Forwar **NOTE**: Your application needs to be able to generate links starting with `VIRTUAL_PATH`. This can be achieved by it being natively on this path or havin an option to prepend this path. The application does not need to expect this path in the request. +#### VIRTUAL_DEST + +This environment variable can be used to rewrite the `VIRTUAL_PATH` part of the requested URL to proxied application. The default value is empty (off). +Make sure that your settings won't result in the slash missing or being doubled. Both these versions can cause troubles. + +If the application runs natively on this sub-path or has a setting to do so, `VIRTUAL_DEST` should not be set or empty. +If the requests are expected to not contain a sub-path and the generated links contain the sub-path, `VIRTUAL_DEST=/` should be used. + +```console +$ docker run -d -e VIRTUAL_HOST=example.tld -e VIRTUAL_PATH=/app1/ -e VIRTUAL_DEST=/ --name app1 app +``` + +In this example, the incoming request `http://example.tld/app1/foo` will be proxied as `http://app1/foo` instead of `http://app1/app1/foo`. + #### DEFAULT_ROOT This environment variable of the nginx proxy container can be used to customize the return error page if no matching path is found. Furthermore it is possible to use anything which is compatible with the `return` statement of nginx. diff --git a/nginx.tmpl b/nginx.tmpl index 85ccbda..b1e6249 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -62,7 +62,7 @@ location {{ .Path }} { {{ else if eq .Proto "grpc" }} grpc_pass {{ trim .Proto }}://{{ trim .Upstream }}; {{ else }} - proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}/; + proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}{{ trim .Dest }}; {{ end }} {{ if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }} @@ -386,12 +386,13 @@ server { {{ end }} {{ if eq $nPaths 0 }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "") }} {{ else }} {{ range $path, $container := $paths }} {{ $sum := sha1 $path }} {{ $upstream := printf "%s-%s" $upstream_name $sum }} - {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root) }} + {{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest) }} {{ end }} {{ if (not (contains $paths "/")) }} location / { @@ -428,12 +429,13 @@ server { {{ end }} {{ if eq $nPaths 0 }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "") }} {{ else }} {{ range $path, $container := $paths }} {{ $sum := sha1 $path }} {{ $upstream := printf "%s-%s" $upstream_name $sum }} - {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root) }} + {{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest) }} {{ end }} {{ if (not (contains $paths "/")) }} location / { diff --git a/test/test_virtual-path/test_custom_conf.yml b/test/test_virtual-path/test_custom_conf.yml index 2fffd65..2369bac 100644 --- a/test/test_virtual-path/test_custom_conf.yml +++ b/test/test_virtual-path/test_custom_conf.yml @@ -6,6 +6,7 @@ web1: WEB_PORTS: "81" VIRTUAL_HOST: "nginx-proxy.test" VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" web2: image: web @@ -15,6 +16,8 @@ web2: WEB_PORTS: "82" VIRTUAL_HOST: "nginx-proxy.test" VIRTUAL_PATH: "/web2/" + VIRTUAL_DEST: "/" + sut: image: nginxproxy/nginx-proxy:test environment: diff --git a/test/test_virtual-path/test_virtual_paths.yml b/test/test_virtual-path/test_virtual_paths.yml index ca688eb..b335c3f 100644 --- a/test/test_virtual-path/test_virtual_paths.yml +++ b/test/test_virtual-path/test_virtual_paths.yml @@ -15,6 +15,7 @@ web1: WEB_PORTS: "81" VIRTUAL_HOST: "nginx-proxy.test" VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" web2: image: web @@ -24,6 +25,7 @@ web2: WEB_PORTS: "82" VIRTUAL_HOST: "nginx-proxy.test" VIRTUAL_PATH: "/web2/" + VIRTUAL_DEST: "/" web3: image: web From 33eab70d321b727b245f5d59056b8a990048eb68 Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 6 Jul 2021 15:41:14 +0200 Subject: [PATCH 40/71] feat: Add custom location block to virtual paths This features allows the custom location blocks to be added to the virtual path based routing. The custom config can be specified for each container individually. --- README.md | 9 ++++++ nginx.tmpl | 2 ++ test/test_virtual-path/alternate.conf | 1 + test/test_virtual-path/bar.conf | 1 + test/test_virtual-path/foo.conf | 1 + test/test_virtual-path/test_custom_conf.py | 32 +++++++++++++++++++++ test/test_virtual-path/test_custom_conf.yml | 22 ++++++++++++++ 7 files changed, 68 insertions(+) create mode 100644 test/test_virtual-path/alternate.conf create mode 100644 test/test_virtual-path/bar.conf create mode 100644 test/test_virtual-path/foo.conf diff --git a/README.md b/README.md index 33ec073..2f00d1c 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ You can also use wildcards at the beginning and the end of host name, like `*.ba ### Path-based Routing You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`. +It is also possible to specify multiple paths with regex locations like `VIRTUAL_PATH=~^/(app1|alternative1)/`. For further details see the nginx documentation on location blocks. This is not compatible with `VIRTUAL_DEST`. The full request URI will be forwarded to the serving container in the `X-Forwarded-Path` header. @@ -139,6 +140,14 @@ $ docker run -d -e VIRTUAL_HOST=example.tld -e VIRTUAL_PATH=/app1/ -e VIRTUAL_DE In this example, the incoming request `http://example.tld/app1/foo` will be proxied as `http://app1/foo` instead of `http://app1/app1/foo`. +#### Per-VIRTUAL_PATH location configuration + +The same options as from [Per-VIRTUAL_HOST location configuration](#Per-VIRTUAL_HOST-location-configuration) are available on a `VIRTUAL_PATH` basis. +The only difference is that the filename gets an additional block `HASH=$(echo -n $VIRTUAL_PATH | sha1sum | awk '{ print $1 }')`. This is the sha1-hash of the `VIRTUAL_PATH` (no newline). This is done filename sanitization purposes. +The used filename is `${VIRTUAL_HOST}_${HASH}_location` + +The filename of the previous example would be `example.tld_8610f6c344b4096614eab6e09d58885349f42faf_location`. + #### DEFAULT_ROOT This environment variable of the nginx proxy container can be used to customize the return error page if no matching path is found. Furthermore it is possible to use anything which is compatible with the `return` statement of nginx. diff --git a/nginx.tmpl b/nginx.tmpl index b1e6249..dd48d4b 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -72,6 +72,8 @@ location {{ .Path }} { {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }} include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}}; + {{ else if (exists (printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) )) }} + include {{ printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) }}; {{ else if (exists "/etc/nginx/vhost.d/default_location") }} include /etc/nginx/vhost.d/default_location; {{ end }} diff --git a/test/test_virtual-path/alternate.conf b/test/test_virtual-path/alternate.conf new file mode 100644 index 0000000..541332e --- /dev/null +++ b/test/test_virtual-path/alternate.conf @@ -0,0 +1 @@ +rewrite ^/(web3|alt)/(.*) /$2 break; diff --git a/test/test_virtual-path/bar.conf b/test/test_virtual-path/bar.conf new file mode 100644 index 0000000..e8b0827 --- /dev/null +++ b/test/test_virtual-path/bar.conf @@ -0,0 +1 @@ +add_header X-test bar; diff --git a/test/test_virtual-path/foo.conf b/test/test_virtual-path/foo.conf new file mode 100644 index 0000000..8d8502d --- /dev/null +++ b/test/test_virtual-path/foo.conf @@ -0,0 +1 @@ +add_header X-test f00; \ No newline at end of file diff --git a/test/test_virtual-path/test_custom_conf.py b/test/test_virtual-path/test_custom_conf.py index 68ecd3a..eec149f 100644 --- a/test/test_virtual-path/test_custom_conf.py +++ b/test/test_virtual-path/test_custom_conf.py @@ -4,3 +4,35 @@ def test_default_root_response(docker_compose, nginxproxy): r = nginxproxy.get("http://nginx-proxy.test/") assert r.status_code == 418 +@pytest.mark.parametrize("stub,header", [ + ("nginx-proxy.test/web1", "bar"), + ("foo.nginx-proxy.test", "f00"), +]) +def test_custom_applies(docker_compose, nginxproxy, stub, header): + r = nginxproxy.get(f"http://{stub}/port") + assert r.status_code == 200 + assert "X-test" in r.headers + assert header == r.headers["X-test"] + +@pytest.mark.parametrize("stub,code", [ + ("nginx-proxy.test/foo", 418), + ("nginx-proxy.test/web2", 200), + ("nginx-proxy.test/web3", 200), + ("bar.nginx-proxy.test", 503), +]) +def test_custom_does_not_apply(docker_compose, nginxproxy, stub, code): + r = nginxproxy.get(f"http://{stub}/port") + assert r.status_code == code + assert "X-test" not in r.headers + +@pytest.mark.parametrize("stub,port", [ + ("nginx-proxy.test/web1", 81), + ("nginx-proxy.test/web2", 82), + ("nginx-proxy.test/web3", 83), + ("nginx-proxy.test/alt", 83), +]) +def test_alternate(docker_compose, nginxproxy, stub, port): + r = nginxproxy.get(f"http://{stub}/port") + assert r.status_code == 200 + assert r.text == f"answer from port {port}\n" + diff --git a/test/test_virtual-path/test_custom_conf.yml b/test/test_virtual-path/test_custom_conf.yml index 2369bac..abd9d0c 100644 --- a/test/test_virtual-path/test_custom_conf.yml +++ b/test/test_virtual-path/test_custom_conf.yml @@ -1,3 +1,12 @@ + +foo: + image: web + expose: + - "42" + environment: + WEB_PORTS: "42" + VIRTUAL_HOST: "foo.nginx-proxy.test" + web1: image: web expose: @@ -18,6 +27,15 @@ web2: VIRTUAL_PATH: "/web2/" VIRTUAL_DEST: "/" +web3: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "~ ^/(web3|alt)/" + sut: image: nginxproxy/nginx-proxy:test environment: @@ -25,3 +43,7 @@ sut: volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro + - ./foo.conf:/etc/nginx/vhost.d/foo.nginx-proxy.test:ro + - ./bar.conf:/etc/nginx/vhost.d/nginx-proxy.test_918d687a929083edd0c7224ee2293e0e7c062ab4_location:ro + - ./alternate.conf:/etc/nginx/vhost.d/nginx-proxy.test_7fb22b74bbdf907425dbbad18e4462565cada230_location:ro + From c75622db87abf0aee6eb97affa95474ea0b2573b Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 13 Aug 2021 10:54:12 +0200 Subject: [PATCH 41/71] docs: fix typo in README.md Co-authored-by: Jonathan Underwood --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f00d1c..9a69d1c 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ It is also possible to specify multiple paths with regex locations like `VIRTUAL The full request URI will be forwarded to the serving container in the `X-Forwarded-Path` header. -**NOTE**: Your application needs to be able to generate links starting with `VIRTUAL_PATH`. This can be achieved by it being natively on this path or havin an option to prepend this path. The application does not need to expect this path in the request. +**NOTE**: Your application needs to be able to generate links starting with `VIRTUAL_PATH`. This can be achieved by it being natively on this path or having an option to prepend this path. The application does not need to expect this path in the request. #### VIRTUAL_DEST From efb250da0120854e4f399d58e4a4c2e2db82333e Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 14 Aug 2021 21:38:13 +0200 Subject: [PATCH 42/71] fix: use most specific custom location config first Co-authored-by: Jonathan Underwood --- nginx.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index dd48d4b..c0f6db5 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -70,10 +70,10 @@ location {{ .Path }} { auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" .Host) }}; {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}}; - {{ else if (exists (printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) )) }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) )) }} include {{ printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) }}; + {{ else if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}}; {{ else if (exists "/etc/nginx/vhost.d/default_location") }} include /etc/nginx/vhost.d/default_location; {{ end }} From 12887a977b3570e27775f19c13563d68ded4314e Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 14 Aug 2021 21:40:25 +0200 Subject: [PATCH 43/71] docs: update DEFAULT_ROOT documentation Co-authored-by: Jonathan Underwood --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 9a69d1c..880d0e8 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,11 @@ This environment variable of the nginx proxy container can be used to customize For example `DEFAUL_ROOT=418` will return a 418 error page instead of the normal 404 one. Another example is `DEFAULT_ROOT="301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` which would redirect an invalid request to this documentation. +Nginx variables such as $scheme, $host, and $request_uri can be used. However, care must be taken to make sure the $ signs are escaped properly. +If you want to use `301 $scheme://$host/myapp1$request_uri` you should use: + +* Bash: `DEFAULT_ROOT='301 $scheme://$host/myapp1$request_uri'` +* Docker Compose yaml: `- DEFAULT_ROOT: 301 $$scheme://$$host/myapp1$$request_uri` ### Multiple Networks From e08b3487c95b38cd3f094e86f9638a39c12bbf84 Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 17 Aug 2021 10:51:32 +0200 Subject: [PATCH 44/71] test: Add test to cover SSL of path-based routing --- test/test_ssl/test_virtual_path.py | 15 +++++++++++++++ test/test_ssl/test_virtual_path.yml | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/test_ssl/test_virtual_path.py create mode 100644 test/test_ssl/test_virtual_path.yml diff --git a/test/test_ssl/test_virtual_path.py b/test/test_ssl/test_virtual_path.py new file mode 100644 index 0000000..508653f --- /dev/null +++ b/test/test_ssl/test_virtual_path.py @@ -0,0 +1,15 @@ +import pytest + +@pytest.mark.parametrize("path", ["web1", "web2"]) +def test_web1_http_redirects_to_https(docker_compose, nginxproxy, path): + r = nginxproxy.get("http://www.nginx-proxy.tld/%s/port" % path, allow_redirects=False) + assert r.status_code == 301 + assert "Location" in r.headers + assert "https://www.nginx-proxy.tld/%s/port" % path == r.headers['Location'] + +@pytest.mark.parametrize("path,port", [("web1", 81), ("web2", 82)]) +def test_web1_https_is_forwarded(docker_compose, nginxproxy, path, port): + r = nginxproxy.get("https://www.nginx-proxy.tld/%s/port" % path, allow_redirects=False) + assert r.status_code == 200 + assert "answer from port %d\n" % port in r.text + diff --git a/test/test_ssl/test_virtual_path.yml b/test/test_ssl/test_virtual_path.yml new file mode 100644 index 0000000..07175ac --- /dev/null +++ b/test/test_ssl/test_virtual_path.yml @@ -0,0 +1,27 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "www.nginx-proxy.tld" + VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" + +web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "www.nginx-proxy.tld" + VIRTUAL_PATH: "/web2/" + VIRTUAL_DEST: "/" + +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 + - ./certs:/etc/nginx/certs:ro + From 4099fcd61872fe4093323771090ccad570a80e77 Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 17 Aug 2021 11:08:56 +0200 Subject: [PATCH 45/71] test: Add test case for default app redirect Co-authored-by: Jonathan Underwood --- test/test_virtual-path/test_forwarding.py | 18 ++++++++++++++++++ test/test_virtual-path/test_forwarding.yml | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/test_virtual-path/test_forwarding.py create mode 100644 test/test_virtual-path/test_forwarding.yml diff --git a/test/test_virtual-path/test_forwarding.py b/test/test_virtual-path/test_forwarding.py new file mode 100644 index 0000000..062dd6c --- /dev/null +++ b/test/test_virtual-path/test_forwarding.py @@ -0,0 +1,18 @@ +import pytest + +def test_root_redirects_to_web1(docker_compose, nginxproxy): + r = nginxproxy.get("http://www.nginx-proxy.tld/port", allow_redirects=False) + assert r.status_code == 301 + assert "Location" in r.headers + assert "http://www.nginx-proxy.tld/web1/port" == r.headers['Location'] + +def test_direct_access(docker_compose, nginxproxy): + r = nginxproxy.get("http://www.nginx-proxy.tld/web1/port", allow_redirects=False) + assert r.status_code == 200 + assert "answer from port 81\n" in r.text + +def test_root_is_forwarded(docker_compose, nginxproxy): + r = nginxproxy.get("http://www.nginx-proxy.tld/port", allow_redirects=True) + assert r.status_code == 200 + assert "answer from port 81\n" in r.text + diff --git a/test/test_virtual-path/test_forwarding.yml b/test/test_virtual-path/test_forwarding.yml new file mode 100644 index 0000000..78662d8 --- /dev/null +++ b/test/test_virtual-path/test_forwarding.yml @@ -0,0 +1,18 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "www.nginx-proxy.tld" + VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" + +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 + - ./certs:/etc/nginx/certs:ro + environment: + - DEFAULT_ROOT=301 http://$$host/web1$$request_uri From 6a580ad66435b7d2b81a3df0cfb857636db46ef3 Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Wed, 18 Aug 2021 15:34:30 +0200 Subject: [PATCH 46/71] test: Add test case for location config priority --- test/test_virtual-path/default.conf | 1 + test/test_virtual-path/host.conf | 1 + test/test_virtual-path/path.conf | 1 + .../test_location_precedence.py | 32 ++++++++++++++++ .../test_location_precedence.yml | 38 +++++++++++++++++++ 5 files changed, 73 insertions(+) create mode 100644 test/test_virtual-path/default.conf create mode 100644 test/test_virtual-path/host.conf create mode 100644 test/test_virtual-path/path.conf create mode 100644 test/test_virtual-path/test_location_precedence.py create mode 100644 test/test_virtual-path/test_location_precedence.yml diff --git a/test/test_virtual-path/default.conf b/test/test_virtual-path/default.conf new file mode 100644 index 0000000..087e66c --- /dev/null +++ b/test/test_virtual-path/default.conf @@ -0,0 +1 @@ +add_header X-test-default true; diff --git a/test/test_virtual-path/host.conf b/test/test_virtual-path/host.conf new file mode 100644 index 0000000..fe05265 --- /dev/null +++ b/test/test_virtual-path/host.conf @@ -0,0 +1 @@ +add_header X-test-host true; diff --git a/test/test_virtual-path/path.conf b/test/test_virtual-path/path.conf new file mode 100644 index 0000000..6c23b9a --- /dev/null +++ b/test/test_virtual-path/path.conf @@ -0,0 +1 @@ +add_header X-test-path true; diff --git a/test/test_virtual-path/test_location_precedence.py b/test/test_virtual-path/test_location_precedence.py new file mode 100644 index 0000000..415c6c1 --- /dev/null +++ b/test/test_virtual-path/test_location_precedence.py @@ -0,0 +1,32 @@ +import pytest + +def test_location_precedence_case1(docker_compose, nginxproxy): + r = nginxproxy.get(f"http://foo.nginx-proxy.test/web1/port") + assert r.status_code == 200 + + assert "X-test-default" in r.headers + assert "X-test-host" not in r.headers + assert "X-test-path" not in r.headers + + assert r.headers["X-test-default"] == "true" + +def test_location_precedence_case2(docker_compose, nginxproxy): + r = nginxproxy.get(f"http://bar.nginx-proxy.test/web2/port") + assert r.status_code == 200 + + assert "X-test-default" not in r.headers + assert "X-test-host" in r.headers + assert "X-test-path" not in r.headers + + assert r.headers["X-test-host"] == "true" + +def test_location_precedence_case3(docker_compose, nginxproxy): + r = nginxproxy.get(f"http://bar.nginx-proxy.test/web3/port") + assert r.status_code == 200 + + assert "X-test-default" not in r.headers + assert "X-test-host" not in r.headers + assert "X-test-path" in r.headers + + assert r.headers["X-test-path"] == "true" + diff --git a/test/test_virtual-path/test_location_precedence.yml b/test/test_virtual-path/test_location_precedence.yml new file mode 100644 index 0000000..be93b58 --- /dev/null +++ b/test/test_virtual-path/test_location_precedence.yml @@ -0,0 +1,38 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "foo.nginx-proxy.test" + VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" + +web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "bar.nginx-proxy.test" + VIRTUAL_PATH: "/web2/" + VIRTUAL_DEST: "/" + +web3: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: "bar.nginx-proxy.test" + VIRTUAL_PATH: "/web3/" + VIRTUAL_DEST: "/" + +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 + - ./default.conf:/etc/nginx/vhost.d/default_location:ro + - ./host.conf:/etc/nginx/vhost.d/bar.nginx-proxy.test_location:ro + - ./path.conf:/etc/nginx/vhost.d/bar.nginx-proxy.test_99f2db0ed8aa95dbb5b87fca79c7eff2ff6bb8bd_location:ro From 28c74e8daeb0eb7f5bcace7db4c5b570af6b5436 Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 24 Aug 2021 15:51:39 +0200 Subject: [PATCH 47/71] fix: Move NETWORK_ACCESS to location block --- network_internal.conf | 1 + nginx.tmpl | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/network_internal.conf b/network_internal.conf index cdf3c9c..bacceb1 100644 --- a/network_internal.conf +++ b/network_internal.conf @@ -3,4 +3,5 @@ allow 127.0.0.0/8; allow 10.0.0.0/8; allow 192.168.0.0/16; allow 172.16.0.0/12; +allow fc00::/7; # IPv6 local address range deny all; diff --git a/nginx.tmpl b/nginx.tmpl index c0f6db5..13ca7a4 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -52,6 +52,11 @@ {{ define "location" }} location {{ .Path }} { + {{ if eq .NetworkTag "internal" }} + # Only allow traffic from internal clients + include /etc/nginx/network_internal.conf; + {{ end }} + {{ if eq .Proto "uwsgi" }} include uwsgi_params; uwsgi_pass {{ trim .Proto }}://{{ trim .Upstream }}; @@ -277,8 +282,6 @@ server { {{/* Get the SERVER_TOKENS defined by containers w/ the same vhost, falling back to "" */}} {{ $server_tokens := trim (or (first (groupByKeys $containers "Env.SERVER_TOKENS")) "") }} -{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} -{{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} {{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}} {{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) (or $.Env.HTTPS_METHOD "redirect") }} @@ -353,11 +356,6 @@ server { {{ end }} {{ $access_log }} - {{ if eq $network_tag "internal" }} - # Only allow traffic from internal clients - include /etc/nginx/network_internal.conf; - {{ end }} - {{ template "ssl_policy" (dict "ssl_policy" $ssl_policy) }} ssl_session_timeout 5m; @@ -388,13 +386,17 @@ server { {{ end }} {{ if eq $nPaths 0 }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "") }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} + {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} {{ else }} {{ range $path, $container := $paths }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} + {{ $network_tag := or (first (groupByKeys $container "Env.NETWORK_ACCESS")) "external" }} {{ $sum := sha1 $path }} {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }} - {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }} {{ end }} {{ if (not (contains $paths "/")) }} location / { @@ -419,11 +421,6 @@ server { {{ end }} {{ $access_log }} - {{ if eq $network_tag "internal" }} - # Only allow traffic from internal clients - include /etc/nginx/network_internal.conf; - {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; {{ else if (exists "/etc/nginx/vhost.d/default") }} @@ -431,13 +428,17 @@ server { {{ end }} {{ if eq $nPaths 0 }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "") }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} + {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} {{ else }} {{ range $path, $container := $paths }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} + {{ $network_tag := or (first (groupByKeys $container "Env.NETWORK_ACCESS")) "external" }} {{ $sum := sha1 $path }} {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }} - {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }} {{ end }} {{ if (not (contains $paths "/")) }} location / { From 2509fc1076d50832e124955a829c7a94634be98e Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Mon, 30 Aug 2021 12:19:10 +0200 Subject: [PATCH 48/71] test: Add test cases for NETWORK_ACCESS=internal --- test/test_internal/network_internal.conf | 11 ++++++++++ test/test_internal/test_per-vhost.py | 14 ++++++++++++ test/test_internal/test_per-vhost.yml | 24 ++++++++++++++++++++ test/test_internal/test_per-vpath.py | 14 ++++++++++++ test/test_internal/test_per-vpath.yml | 28 ++++++++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 test/test_internal/network_internal.conf create mode 100644 test/test_internal/test_per-vhost.py create mode 100644 test/test_internal/test_per-vhost.yml create mode 100644 test/test_internal/test_per-vpath.py create mode 100644 test/test_internal/test_per-vpath.yml diff --git a/test/test_internal/network_internal.conf b/test/test_internal/network_internal.conf new file mode 100644 index 0000000..496e569 --- /dev/null +++ b/test/test_internal/network_internal.conf @@ -0,0 +1,11 @@ +# Only allow traffic from internal clients +allow 127.0.0.0/8; +allow 10.0.0.0/8; +allow 192.168.0.0/16; +allow 172.16.0.0/12; +allow fc00::/7; # IPv6 local address range +deny all; + +# Dummy header for testing +add_header X-network internal; + diff --git a/test/test_internal/test_per-vhost.py b/test/test_internal/test_per-vhost.py new file mode 100644 index 0000000..4586cc0 --- /dev/null +++ b/test/test_internal/test_per-vhost.py @@ -0,0 +1,14 @@ +import pytest + +def test_network_web1(docker_compose, nginxproxy): + r = nginxproxy.get("http://web1.nginx-proxy.local/port") + assert r.status_code == 200 + assert r.text == "answer from port 81\n" + assert "X-network" in r.headers + assert "internal" == r.headers["X-network"] + +def test_network_web2(docker_compose, nginxproxy): + r = nginxproxy.get("http://web2.nginx-proxy.local/port") + assert r.status_code == 200 + assert r.text == "answer from port 82\n" + assert "X-network" not in r.headers diff --git a/test/test_internal/test_per-vhost.yml b/test/test_internal/test_per-vhost.yml new file mode 100644 index 0000000..a935e53 --- /dev/null +++ b/test/test_internal/test_per-vhost.yml @@ -0,0 +1,24 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web1.nginx-proxy.local + NETWORK_ACCESS: internal + +web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: 82 + VIRTUAL_HOST: web2.nginx-proxy.local + +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 + - ./network_internal.conf:/etc/nginx/network_internal.conf:ro + diff --git a/test/test_internal/test_per-vpath.py b/test/test_internal/test_per-vpath.py new file mode 100644 index 0000000..e95fe00 --- /dev/null +++ b/test/test_internal/test_per-vpath.py @@ -0,0 +1,14 @@ +import pytest + +def test_network_web1(docker_compose, nginxproxy): + r = nginxproxy.get("http://nginx-proxy.local/web1/port") + assert r.status_code == 200 + assert r.text == "answer from port 81\n" + assert "X-network" in r.headers + assert "internal" == r.headers["X-network"] + +def test_network_web2(docker_compose, nginxproxy): + r = nginxproxy.get("http://nginx-proxy.local/web2/port") + assert r.status_code == 200 + assert r.text == "answer from port 82\n" + assert "X-network" not in r.headers diff --git a/test/test_internal/test_per-vpath.yml b/test/test_internal/test_per-vpath.yml new file mode 100644 index 0000000..1ea470f --- /dev/null +++ b/test/test_internal/test_per-vpath.yml @@ -0,0 +1,28 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: nginx-proxy.local + VIRTUAL_PATH: /web1/ + VIRTUAL_DEST: / + NETWORK_ACCESS: internal + +web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: 82 + VIRTUAL_HOST: nginx-proxy.local + VIRTUAL_PATH: /web2/ + VIRTUAL_DEST: / + +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 + - ./network_internal.conf:/etc/nginx/network_internal.conf:ro + From 7ede0fa4b97840c02aeac5498c43d616c74b6221 Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Mon, 30 Aug 2021 14:37:28 +0200 Subject: [PATCH 49/71] test: fix: Rename new test files --- .../{test_per-vhost.py => test_internal-per-vhost.py} | 0 .../{test_per-vhost.yml => test_internal-per-vhost.yml} | 0 .../{test_per-vpath.py => test_internal-per-vpath.py} | 0 .../{test_per-vpath.yml => test_internal-per-vpath.yml} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename test/test_internal/{test_per-vhost.py => test_internal-per-vhost.py} (100%) rename test/test_internal/{test_per-vhost.yml => test_internal-per-vhost.yml} (100%) rename test/test_internal/{test_per-vpath.py => test_internal-per-vpath.py} (100%) rename test/test_internal/{test_per-vpath.yml => test_internal-per-vpath.yml} (100%) diff --git a/test/test_internal/test_per-vhost.py b/test/test_internal/test_internal-per-vhost.py similarity index 100% rename from test/test_internal/test_per-vhost.py rename to test/test_internal/test_internal-per-vhost.py diff --git a/test/test_internal/test_per-vhost.yml b/test/test_internal/test_internal-per-vhost.yml similarity index 100% rename from test/test_internal/test_per-vhost.yml rename to test/test_internal/test_internal-per-vhost.yml diff --git a/test/test_internal/test_per-vpath.py b/test/test_internal/test_internal-per-vpath.py similarity index 100% rename from test/test_internal/test_per-vpath.py rename to test/test_internal/test_internal-per-vpath.py diff --git a/test/test_internal/test_per-vpath.yml b/test/test_internal/test_internal-per-vpath.yml similarity index 100% rename from test/test_internal/test_per-vpath.yml rename to test/test_internal/test_internal-per-vpath.yml From 08c9586346703dfa7035404ca7ab724afd3a0e54 Mon Sep 17 00:00:00 2001 From: Alexander Lieret Date: Tue, 21 Sep 2021 14:07:41 +0200 Subject: [PATCH 50/71] fix: Handle VIRTUAL_PROTO on virtual path basis --- nginx.tmpl | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 13ca7a4..0eeeac9 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -276,9 +276,6 @@ server { {{ $default_host := or ($.Env.DEFAULT_HOST) "" }} {{ $default_server := index (dict $host "" $default_host "default_server") $host }} -{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} -{{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }} - {{/* Get the SERVER_TOKENS defined by containers w/ the same vhost, falling back to "" */}} {{ $server_tokens := trim (or (first (groupByKeys $containers "Env.SERVER_TOKENS")) "") }} @@ -386,11 +383,17 @@ server { {{ end }} {{ if eq $nPaths 0 }} + {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} + {{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} {{ else }} {{ range $path, $container := $paths }} + {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost-vpath, falling back to "http" */}} + {{ $proto := trim (or (first (groupByKeys $container "Env.VIRTUAL_PROTO")) "http") }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} {{ $network_tag := or (first (groupByKeys $container "Env.NETWORK_ACCESS")) "external" }} {{ $sum := sha1 $path }} @@ -428,11 +431,17 @@ server { {{ end }} {{ if eq $nPaths 0 }} + {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} + {{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} {{ else }} {{ range $path, $container := $paths }} + {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost-vpath, falling back to "http" */}} + {{ $proto := trim (or (first (groupByKeys $container "Env.VIRTUAL_PROTO")) "http") }} + {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} {{ $network_tag := or (first (groupByKeys $container "Env.NETWORK_ACCESS")) "external" }} {{ $sum := sha1 $path }} From 01446472dddb3c7ebbe7f69c7269b3461daa9aec Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Thu, 24 Feb 2022 15:08:45 +0100 Subject: [PATCH 51/71] Revert "ci: use docker-gen main on dev branch tests" This reverts commit b6e9cdc065a19ce7e7cb0dcf2c11cd7c9fe1d063. --- .github/workflows/test.yml | 20 ++++---------------- Makefile | 6 ------ 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c4a173..6be93bd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,16 +3,13 @@ name: Tests on: workflow_dispatch: push: - branches: - - main - - dev paths-ignore: - - 'LICENSE' - - '**.md' + - 'LICENSE' + - '**.md' pull_request: paths-ignore: - - 'LICENSE' - - '**.md' + - 'LICENSE' + - '**.md' jobs: unit: @@ -42,15 +39,6 @@ jobs: - name: Build Docker nginx proxy test image run: make build-nginx-proxy-test-${{ matrix.base_docker_image }} - if: | - ( github.event_name == 'push' && github.ref != 'refs/heads/dev' ) || - ( github.event_name == 'pull_request' && github.base_ref != 'dev' ) - - - name: Build Docker nginx proxy dev test image - run: make build-nginx-proxy-test-${{ matrix.base_docker_image }}-dev - if: | - ( github.event_name == 'push' && github.ref == 'refs/heads/dev' ) || - ( github.event_name == 'pull_request' && github.base_ref == 'dev' ) - name: Run tests run: pytest diff --git a/Makefile b/Makefile index 60406b6..ab44880 100644 --- a/Makefile +++ b/Makefile @@ -11,12 +11,6 @@ build-nginx-proxy-test-debian: build-nginx-proxy-test-alpine: docker build --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test . -build-nginx-proxy-test-debian-dev: - docker build --build-arg DOCKER_GEN_VERSION=main -t nginxproxy/nginx-proxy:test . - -build-nginx-proxy-test-alpine-dev: - docker build -f Dockerfile.alpine --build-arg DOCKER_GEN_VERSION=main -t nginxproxy/nginx-proxy:test . - test-debian: build-webserver build-nginx-proxy-test-debian test/pytest.sh From b6b7133a2eba412749a6e90856b98292ce09c3af Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Thu, 24 Feb 2022 15:17:47 +0100 Subject: [PATCH 52/71] fix: minor fixes on nginx template --- nginx.tmpl | 70 +++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 0eeeac9..351cf88 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -61,8 +61,8 @@ location {{ .Path }} { include uwsgi_params; uwsgi_pass {{ trim .Proto }}://{{ trim .Upstream }}; {{ else if eq .Proto "fastcgi" }} - root {{ trim .Vhostroot }}; - include fastcgi.conf; + root {{ trim .VhostRoot }}; + include fastcgi_params; fastcgi_pass {{ trim .Upstream }}; {{ else if eq .Proto "grpc" }} grpc_pass {{ trim .Proto }}://{{ trim .Upstream }}; @@ -85,12 +85,12 @@ location {{ .Path }} { } {{ end }} -{{ define "upstream-definition" }} +{{ define "upstream" }} {{ $networks := .Networks }} {{ $debug_all := .Debug }} upstream {{ .Upstream }} { - {{ $server_found := "false" }} - {{ range $container := .Containers }} + {{ $server_found := "false" }} + {{ range $container := .Containers }} {{ $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 }} @@ -100,46 +100,46 @@ location {{ .Path }} { # Exposed ports: {{ $container.Addresses }} # Default virtual port: {{ $defaultPort }} # VIRTUAL_PORT: {{ $container.Env.VIRTUAL_PORT }} - {{ if not $address }} + {{ if not $address }} # /!\ Virtual port not exposed - {{ end }} + {{ end }} {{ end }} - {{ range $knownNetwork := $networks }} - {{ range $containerNetwork := $container.Networks }} - {{ if (and (ne $containerNetwork.Name "ingress") (or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name "host"))) }} + {{ range $knownNetwork := $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 $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 }} - {{ $server_found = "true" }} + {{ 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 }} + {{ $server_found = "true" }} # {{ $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 $containerNetwork }} - {{ $server_found = "true" }} + {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} + {{ else if $containerNetwork }} + {{ $server_found = "true" }} # {{ $container.Name }} server {{ $containerNetwork.IP }}:{{ $address.Port }}; - {{ end }} - {{ else if $containerNetwork }} + {{ end }} + {{ else if $containerNetwork }} # {{ $container.Name }} - {{ if $containerNetwork.IP }} - {{ $server_found = "true" }} + {{ if $containerNetwork.IP }} + {{ $server_found = "true" }} server {{ $containerNetwork.IP }}:{{ $port }}; - {{ else }} + {{ else }} # /!\ No IP for this network! - {{ end }} - {{ end }} - {{ else }} - # Cannot connect to network '{{ $containerNetwork.Name }}' of this container + {{ end }} {{ end }} + {{ else }} + # Cannot connect to network '{{ $containerNetwork.Name }}' of this container {{ end }} {{ end }} {{ end }} - {{/* nginx-proxy/nginx-proxy#1105 */}} - {{ if (eq $server_found "false") }} + {{ end }} + {{/* nginx-proxy/nginx-proxy#1105 */}} + {{ if (eq $server_found "false") }} # Fallback entry server 127.0.0.1 down; - {{ end }} + {{ end }} } {{ end }} @@ -263,13 +263,13 @@ server { {{ if eq $nPaths 0 }} # {{ $host }} - {{ template "upstream-definition" (dict "Upstream" $upstream_name "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }} + {{ template "upstream" (dict "Upstream" $upstream_name "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }} {{ else }} {{ range $path, $containers := $paths }} {{ $sum := sha1 $path }} {{ $upstream := printf "%s-%s" $upstream_name $sum }} # {{ $host }}{{ $path }} - {{ template "upstream-definition" (dict "Upstream" $upstream "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }} + {{ template "upstream" (dict "Upstream" $upstream "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }} {{ end }} {{ end }} @@ -388,7 +388,7 @@ server { {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "VhostRoot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} {{ else }} {{ range $path, $container := $paths }} {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost-vpath, falling back to "http" */}} @@ -399,7 +399,7 @@ server { {{ $sum := sha1 $path }} {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }} - {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "VhostRoot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }} {{ end }} {{ if (not (contains $paths "/")) }} location / { @@ -436,7 +436,7 @@ server { {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "Vhostroot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "VhostRoot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }} {{ else }} {{ range $path, $container := $paths }} {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost-vpath, falling back to "http" */}} @@ -447,7 +447,7 @@ server { {{ $sum := sha1 $path }} {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }} - {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "Vhostroot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "VhostRoot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }} {{ end }} {{ if (not (contains $paths "/")) }} location / { From 0185a2971c6538afa72021acefd9bfdc1552034d Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Thu, 24 Feb 2022 15:21:14 +0100 Subject: [PATCH 53/71] tests: fix virtual path tests for new dhparam --- test/test_internal/test_internal-per-vhost.yml | 1 - test/test_internal/test_internal-per-vpath.yml | 1 - test/test_ssl/test_virtual_path.yml | 1 - test/test_virtual-path/test_custom_conf.yml | 1 - test/test_virtual-path/test_forwarding.yml | 1 - test/test_virtual-path/test_location_precedence.yml | 1 - test/test_virtual-path/test_virtual_paths.yml | 2 -- 7 files changed, 8 deletions(-) diff --git a/test/test_internal/test_internal-per-vhost.yml b/test/test_internal/test_internal-per-vhost.yml index a935e53..5c732ee 100644 --- a/test/test_internal/test_internal-per-vhost.yml +++ b/test/test_internal/test_internal-per-vhost.yml @@ -19,6 +19,5 @@ 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 - ./network_internal.conf:/etc/nginx/network_internal.conf:ro diff --git a/test/test_internal/test_internal-per-vpath.yml b/test/test_internal/test_internal-per-vpath.yml index 1ea470f..f5bac55 100644 --- a/test/test_internal/test_internal-per-vpath.yml +++ b/test/test_internal/test_internal-per-vpath.yml @@ -23,6 +23,5 @@ 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 - ./network_internal.conf:/etc/nginx/network_internal.conf:ro diff --git a/test/test_ssl/test_virtual_path.yml b/test/test_ssl/test_virtual_path.yml index 07175ac..2260321 100644 --- a/test/test_ssl/test_virtual_path.yml +++ b/test/test_ssl/test_virtual_path.yml @@ -22,6 +22,5 @@ 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 - ./certs:/etc/nginx/certs:ro diff --git a/test/test_virtual-path/test_custom_conf.yml b/test/test_virtual-path/test_custom_conf.yml index abd9d0c..40ab512 100644 --- a/test/test_virtual-path/test_custom_conf.yml +++ b/test/test_virtual-path/test_custom_conf.yml @@ -42,7 +42,6 @@ sut: DEFAULT_ROOT: 418 volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - - ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro - ./foo.conf:/etc/nginx/vhost.d/foo.nginx-proxy.test:ro - ./bar.conf:/etc/nginx/vhost.d/nginx-proxy.test_918d687a929083edd0c7224ee2293e0e7c062ab4_location:ro - ./alternate.conf:/etc/nginx/vhost.d/nginx-proxy.test_7fb22b74bbdf907425dbbad18e4462565cada230_location:ro diff --git a/test/test_virtual-path/test_forwarding.yml b/test/test_virtual-path/test_forwarding.yml index 78662d8..ee87e8d 100644 --- a/test/test_virtual-path/test_forwarding.yml +++ b/test/test_virtual-path/test_forwarding.yml @@ -12,7 +12,6 @@ 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 - ./certs:/etc/nginx/certs:ro environment: - DEFAULT_ROOT=301 http://$$host/web1$$request_uri diff --git a/test/test_virtual-path/test_location_precedence.yml b/test/test_virtual-path/test_location_precedence.yml index be93b58..be3248c 100644 --- a/test/test_virtual-path/test_location_precedence.yml +++ b/test/test_virtual-path/test_location_precedence.yml @@ -32,7 +32,6 @@ 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 - ./default.conf:/etc/nginx/vhost.d/default_location:ro - ./host.conf:/etc/nginx/vhost.d/bar.nginx-proxy.test_location:ro - ./path.conf:/etc/nginx/vhost.d/bar.nginx-proxy.test_99f2db0ed8aa95dbb5b87fca79c7eff2ff6bb8bd_location:ro diff --git a/test/test_virtual-path/test_virtual_paths.yml b/test/test_virtual-path/test_virtual_paths.yml index b335c3f..9f6a54f 100644 --- a/test/test_virtual-path/test_virtual_paths.yml +++ b/test/test_virtual-path/test_virtual_paths.yml @@ -40,5 +40,3 @@ 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 - From 621e703fad4c6ab58fc1248211fe2a674b688e5f Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Thu, 24 Feb 2022 16:21:10 +0100 Subject: [PATCH 54/71] build: docker-gen main -> 0.8.2 --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index bc4093d..9857927 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=main +ARG DOCKER_GEN_VERSION=0.8.2 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 98e9bc5..f8e5b56 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,5 +1,5 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=main +ARG DOCKER_GEN_VERSION=0.8.2 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries From 061d129b1b38af335aad70ef7cd613254927adb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Feb 2022 15:39:59 +0000 Subject: [PATCH 55/71] chore(deps): bump golang from 1.16.7 to 1.17.7 Bumps golang from 1.16.7 to 1.17.7. --- updated-dependencies: - dependency-name: golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9857927..7aa1a77 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG DOCKER_GEN_VERSION=0.8.2 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.16.7 as gobuilder +FROM golang:1.17.7 as gobuilder # Build docker-gen from scratch FROM gobuilder as dockergen diff --git a/Dockerfile.alpine b/Dockerfile.alpine index f8e5b56..ec330a8 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -3,7 +3,7 @@ ARG DOCKER_GEN_VERSION=0.8.2 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.16.7-alpine as gobuilder +FROM golang:1.17.7-alpine as gobuilder RUN apk add --no-cache git musl-dev # Build docker-gen from scratch From fee27ea712eec20e0642043fad6fddf8edad1159 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Thu, 24 Feb 2022 16:43:45 +0100 Subject: [PATCH 56/71] docs: nginx badge 1.21.5 -> 1.21.6 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 880d0e8..dc8414b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Test](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml/badge.svg)](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml) [![GitHub release](https://img.shields.io/github/v/release/nginx-proxy/nginx-proxy)](https://github.com/nginx-proxy/nginx-proxy/releases) -![nginx 1.21.5](https://img.shields.io/badge/nginx-1.21.5-brightgreen.svg) +![nginx 1.21.6](https://img.shields.io/badge/nginx-1.21.6-brightgreen.svg) [![Docker Image Size](https://img.shields.io/docker/image-size/nginxproxy/nginx-proxy?sort=semver)](https://hub.docker.com/r/nginxproxy/nginx-proxy "Click to view the image on Docker Hub") [![Docker stars](https://img.shields.io/docker/stars/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub') [![Docker pulls](https://img.shields.io/docker/pulls/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub') From 5ab320d82aa4338e702b6f7dfa635cbe990b6503 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 4 Mar 2022 10:59:50 +0100 Subject: [PATCH 57/71] ci: publish Docker images to ghcr.io --- .github/workflows/dockerhub.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 74283b7..1630f8a 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -38,6 +38,7 @@ jobs: uses: docker/metadata-action@v3 with: images: | + ghcr.io/nginx-proxy/nginx-proxy nginxproxy/nginx-proxy jwilder/nginx-proxy tags: | @@ -60,6 +61,13 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push the Debian based image if: github.ref == 'refs/heads/main' From 993e5f82824d016366615ec7fc6235ddd620da09 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 4 Mar 2022 11:10:14 +0100 Subject: [PATCH 58/71] ci: publish the alpine image to ghcr.io too --- .github/workflows/dockerhub.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 1630f8a..dfb4286 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -119,6 +119,7 @@ jobs: uses: docker/metadata-action@v3 with: images: | + ghcr.io/nginx-proxy/nginx-proxy nginxproxy/nginx-proxy jwilder/nginx-proxy tags: | @@ -142,6 +143,13 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push the Alpine based image if: github.ref == 'refs/heads/main' From 0ea8a087612807971ebd21ae05a06868120ca5fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Mar 2022 04:11:51 +0000 Subject: [PATCH 59/71] chore(deps): bump golang from 1.17.7 to 1.17.8 Bumps golang from 1.17.7 to 1.17.8. --- updated-dependencies: - dependency-name: golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7aa1a77..16de38c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG DOCKER_GEN_VERSION=0.8.2 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.17.7 as gobuilder +FROM golang:1.17.8 as gobuilder # Build docker-gen from scratch FROM gobuilder as dockergen diff --git a/Dockerfile.alpine b/Dockerfile.alpine index ec330a8..0208de6 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -3,7 +3,7 @@ ARG DOCKER_GEN_VERSION=0.8.2 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.17.7-alpine as gobuilder +FROM golang:1.17.8-alpine as gobuilder RUN apk add --no-cache git musl-dev # Build docker-gen from scratch From 5ee6db5e3e798588edd9433495f16617d688d148 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 7 Mar 2022 14:12:26 +0100 Subject: [PATCH 60/71] ci: remove dev branch build, fix build on tags --- .github/workflows/dockerhub.yml | 40 --------------------------------- 1 file changed, 40 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index dfb4286..706d298 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -7,13 +7,11 @@ on: push: branches: - main - - dev tags: - '*.*.*' paths-ignore: - 'test/*' - '.gitignore' - - '.travis.yml' - 'docker-compose-separate-containers.yml' - 'docker-compose.yml' - 'LICENSE' @@ -45,7 +43,6 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} - type=raw,value=dev,enable=${{ github.ref == 'refs/heads/dev' }} labels: | org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} @@ -70,7 +67,6 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push the Debian based image - if: github.ref == 'refs/heads/main' id: docker_build_debian uses: docker/build-push-action@v2 with: @@ -83,25 +79,8 @@ jobs: labels: ${{ steps.docker_meta_debian.outputs.labels }} - name: Images digests - if: github.ref == 'refs/heads/main' run: echo ${{ steps.docker_build_debian.outputs.digest }} - - name: Build and push the Debian based dev image - if: github.ref == 'refs/heads/dev' - id: docker_build_debian_dev - uses: docker/build-push-action@v2 - with: - file: Dockerfile - build-args: DOCKER_GEN_VERSION=main - platforms: linux/amd64,linux/arm64,linux/arm/v7 - push: true - tags: ${{ steps.docker_meta_debian.outputs.tags }} - labels: ${{ steps.docker_meta_debian.outputs.labels }} - - - name: Images digests - if: github.ref == 'refs/heads/dev' - run: echo ${{ steps.docker_build_debian_dev.outputs.digest }} - multiarch-build-alpine: runs-on: ubuntu-latest steps: @@ -126,7 +105,6 @@ jobs: type=semver,suffix=-alpine,pattern={{version}} type=semver,suffix=-alpine,pattern={{major}}.{{minor}} type=raw,value=alpine,enable=${{ github.ref == 'refs/heads/main' }} - type=raw,value=dev-alpine,enable=${{ github.ref == 'refs/heads/dev' }} labels: | org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder org.opencontainers.image.version=${{ env.GIT_DESCRIBE }} @@ -152,7 +130,6 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push the Alpine based image - if: github.ref == 'refs/heads/main' id: docker_build_alpine uses: docker/build-push-action@v2 with: @@ -165,21 +142,4 @@ jobs: labels: ${{ steps.docker_meta_alpine.outputs.labels }} - name: Images digests - if: github.ref == 'refs/heads/main' run: echo ${{ steps.docker_build_alpine.outputs.digest }} - - - name: Build and push the Alpine based dev image - if: github.ref == 'refs/heads/dev' - id: docker_build_alpine_dev - uses: docker/build-push-action@v2 - with: - file: Dockerfile.alpine - build-args: DOCKER_GEN_VERSION=main - platforms: linux/amd64,linux/arm64,linux/arm/v7 - push: true - tags: ${{ steps.docker_meta_alpine.outputs.tags }} - labels: ${{ steps.docker_meta_alpine.outputs.labels }} - - - name: Images digests - if: github.ref == 'refs/heads/dev' - run: echo ${{ steps.docker_build_alpine_dev.outputs.digest }} From 3257177d80cfcc27d3ae556471a9b87a7af5f92a Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 7 Mar 2022 14:14:16 +0100 Subject: [PATCH 61/71] fix: remove outdated comment from Dockerfiles --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 16de38c..851baa1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -55,7 +55,7 @@ RUN apt-get update \ && rm -r /var/lib/apt/lists/* -# Configure Nginx and apply fix for very long server names +# Configure Nginx RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ && sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf \ && sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 0208de6..7779572 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -52,7 +52,7 @@ RUN apk add --no-cache --virtual .run-deps \ ca-certificates bash wget openssl \ && update-ca-certificates -# Configure Nginx and apply fix for very long server names +# Configure Nginx RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ && sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf \ && sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ From 5aba125fb7b359c44b419a746c052a3806d08d09 Mon Sep 17 00:00:00 2001 From: Gilles Filippini Date: Mon, 1 Jun 2020 07:15:00 +0000 Subject: [PATCH 62/71] chore: do not copy useless files into the image Move required files but 'nginx.tmpl' into a local 'app' folder and copy the folder content into the image. 'nginx.tmpl' should be moved as well, but this is a breaking change for configuration with a separate 'docker-gen' container. --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- Procfile => app/Procfile | 0 {dhparam => app/dhparam}/ffdhe2048.pem | 0 {dhparam => app/dhparam}/ffdhe3072.pem | 0 {dhparam => app/dhparam}/ffdhe4096.pem | 0 docker-entrypoint.sh => app/docker-entrypoint.sh | 0 test/test_ssl/test_dhparam.yml | 2 +- 8 files changed, 3 insertions(+), 3 deletions(-) rename Procfile => app/Procfile (100%) rename {dhparam => app/dhparam}/ffdhe2048.pem (100%) rename {dhparam => app/dhparam}/ffdhe3072.pem (100%) rename {dhparam => app/dhparam}/ffdhe4096.pem (100%) rename docker-entrypoint.sh => app/docker-entrypoint.sh (100%) diff --git a/Dockerfile b/Dockerfile index 851baa1..35a2dbb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -67,7 +67,7 @@ COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen COPY network_internal.conf /etc/nginx/ -COPY . /app/ +COPY app nginx.tmpl /app/ WORKDIR /app/ ENTRYPOINT ["/app/docker-entrypoint.sh"] diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 7779572..602c5f9 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -64,7 +64,7 @@ COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen COPY network_internal.conf /etc/nginx/ -COPY . /app/ +COPY app nginx.tmpl /app/ WORKDIR /app/ ENTRYPOINT ["/app/docker-entrypoint.sh"] diff --git a/Procfile b/app/Procfile similarity index 100% rename from Procfile rename to app/Procfile diff --git a/dhparam/ffdhe2048.pem b/app/dhparam/ffdhe2048.pem similarity index 100% rename from dhparam/ffdhe2048.pem rename to app/dhparam/ffdhe2048.pem diff --git a/dhparam/ffdhe3072.pem b/app/dhparam/ffdhe3072.pem similarity index 100% rename from dhparam/ffdhe3072.pem rename to app/dhparam/ffdhe3072.pem diff --git a/dhparam/ffdhe4096.pem b/app/dhparam/ffdhe4096.pem similarity index 100% rename from dhparam/ffdhe4096.pem rename to app/dhparam/ffdhe4096.pem diff --git a/docker-entrypoint.sh b/app/docker-entrypoint.sh similarity index 100% rename from docker-entrypoint.sh rename to app/docker-entrypoint.sh diff --git a/test/test_ssl/test_dhparam.yml b/test/test_ssl/test_dhparam.yml index fa4fe1e..505ac4c 100644 --- a/test/test_ssl/test_dhparam.yml +++ b/test/test_ssl/test_dhparam.yml @@ -54,7 +54,7 @@ with_custom_file: volumes: - *docker-sock - *nginx-certs - - ../../dhparam/ffdhe3072.pem:/etc/nginx/dhparam/dhparam.pem:ro + - ../../app/dhparam/ffdhe3072.pem:/etc/nginx/dhparam/dhparam.pem:ro with_skip: container_name: dh-skip From fea6cc7537ae3e60d94903be2e0928c0c8941008 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 7 Mar 2022 15:35:49 +0100 Subject: [PATCH 63/71] chore: update .dockerignore --- .dockerignore | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index 8fafbb0..6849862 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,10 @@ .git +.github +test .dockerignore -circle.yml +.gitignore +*.yml +Dockerfile* +LICENSE Makefile README.md -test From 4ea3437dfab423b6710b32b2aa9d50f9f750bed9 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Wed, 9 Mar 2022 12:05:56 +0100 Subject: [PATCH 64/71] chore: include license into the Docker images --- .dockerignore | 1 - Dockerfile | 2 +- Dockerfile.alpine | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index 6849862..aad7a31 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,5 @@ test .gitignore *.yml Dockerfile* -LICENSE Makefile README.md diff --git a/Dockerfile b/Dockerfile index 35a2dbb..8a46d97 100644 --- a/Dockerfile +++ b/Dockerfile @@ -67,7 +67,7 @@ COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen COPY network_internal.conf /etc/nginx/ -COPY app nginx.tmpl /app/ +COPY app nginx.tmpl LICENSE /app/ WORKDIR /app/ ENTRYPOINT ["/app/docker-entrypoint.sh"] diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 602c5f9..cc1247e 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -64,7 +64,7 @@ COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen COPY network_internal.conf /etc/nginx/ -COPY app nginx.tmpl /app/ +COPY app nginx.tmpl LICENSE /app/ WORKDIR /app/ ENTRYPOINT ["/app/docker-entrypoint.sh"] From 1cc3bbf5cea53a78dd9a830d7948f3e9ebd5b3e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Mar 2022 04:16:58 +0000 Subject: [PATCH 65/71] chore(deps): bump pytest from 7.0.1 to 7.1.1 in /test/requirements Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.0.1 to 7.1.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.0.1...7.1.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- test/requirements/python-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements/python-requirements.txt b/test/requirements/python-requirements.txt index 3747455..865bb27 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -1,5 +1,5 @@ backoff==1.11.1 docker-compose==1.29.2 docker==5.0.3 -pytest==7.0.1 +pytest==7.1.1 requests==2.27.1 From 55d913255d82f78f62a41c490d82b00454701b40 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Sun, 20 Mar 2022 18:54:07 -0400 Subject: [PATCH 66/71] Fix IPv6 HTTP listen port --- nginx.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index 351cf88..610edf1 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -420,7 +420,7 @@ server { {{ end }} listen {{ $external_http_port }} {{ $default_server }}; {{ if $enable_ipv6 }} - listen [::]:80 {{ $default_server }}; + listen [::]:{{ $external_http_port }} {{ $default_server }}; {{ end }} {{ $access_log }} From 6a0a1f67825dfb5beb7fe58aaaa611773a212a30 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 25 Mar 2022 11:05:17 +0100 Subject: [PATCH 67/71] build: bump docker-gen from 0.8.2 to 0.8.4 --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8a46d97..46524b8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=0.8.2 +ARG DOCKER_GEN_VERSION=0.8.4 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries diff --git a/Dockerfile.alpine b/Dockerfile.alpine index cc1247e..14f558e 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,5 +1,5 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=0.8.2 +ARG DOCKER_GEN_VERSION=0.8.4 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries From 2e1da37f9af3dbd4a70a8095fab1d55bb972ef9b Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sun, 10 Apr 2022 13:15:02 +0200 Subject: [PATCH 68/71] build: bump docker-gen from 0.8.4 to 0.9.0 --- Dockerfile | 4 ++-- Dockerfile.alpine | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 46524b8..168858b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=0.8.4 +ARG DOCKER_GEN_VERSION=0.9.0 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.17.8 as gobuilder +FROM golang:1.18.0 as gobuilder # Build docker-gen from scratch FROM gobuilder as dockergen diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 14f558e..f98c4b8 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,9 +1,9 @@ # setup build arguments for version of dependencies to use -ARG DOCKER_GEN_VERSION=0.8.4 +ARG DOCKER_GEN_VERSION=0.9.0 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.17.8-alpine as gobuilder +FROM golang:1.18.0-alpine as gobuilder RUN apk add --no-cache git musl-dev # Build docker-gen from scratch From ae0faa43cd3b452bc576a4f440fff22b19589301 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Apr 2022 04:10:10 +0000 Subject: [PATCH 69/71] chore(deps): bump golang from 1.18.0 to 1.18.1 Bumps golang from 1.18.0 to 1.18.1. --- updated-dependencies: - dependency-name: golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 168858b..dcd0285 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG DOCKER_GEN_VERSION=0.9.0 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.18.0 as gobuilder +FROM golang:1.18.1 as gobuilder # Build docker-gen from scratch FROM gobuilder as dockergen diff --git a/Dockerfile.alpine b/Dockerfile.alpine index f98c4b8..51cafd9 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -3,7 +3,7 @@ ARG DOCKER_GEN_VERSION=0.9.0 ARG FOREGO_VERSION=v0.17.0 # Use a specific version of golang to build both binaries -FROM golang:1.18.0-alpine as gobuilder +FROM golang:1.18.1-alpine as gobuilder RUN apk add --no-cache git musl-dev # Build docker-gen from scratch From 998d56c473079901b788c6ddc297307016362419 Mon Sep 17 00:00:00 2001 From: Nitin Jain Date: Wed, 6 Apr 2022 16:24:27 +0530 Subject: [PATCH 70/71] chore: indent location, upstream in template --- nginx.tmpl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 610edf1..e8a555d 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -51,10 +51,10 @@ {{ end }} {{ define "location" }} -location {{ .Path }} { + location {{ .Path }} { {{ if eq .NetworkTag "internal" }} - # Only allow traffic from internal clients - include /etc/nginx/network_internal.conf; + # Only allow traffic from internal clients + include /etc/nginx/network_internal.conf; {{ end }} {{ if eq .Proto "uwsgi" }} @@ -88,7 +88,7 @@ location {{ .Path }} { {{ define "upstream" }} {{ $networks := .Networks }} {{ $debug_all := .Debug }} - upstream {{ .Upstream }} { +upstream {{ .Upstream }} { {{ $server_found := "false" }} {{ range $container := .Containers }} {{ $debug := (eq (coalesce $container.Env.DEBUG $debug_all "false") "true") }} @@ -140,7 +140,7 @@ location {{ .Path }} { # Fallback entry server 127.0.0.1 down; {{ end }} - } +} {{ end }} {{ if ne $nginx_proxy_version "" }} From 20e76ac7a68f89060bb234c58dfb99f3d3d3fb9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 04:22:00 +0000 Subject: [PATCH 71/71] chore(deps): bump pytest from 7.1.1 to 7.1.2 in /test/requirements Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.1 to 7.1.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.1.1...7.1.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- test/requirements/python-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements/python-requirements.txt b/test/requirements/python-requirements.txt index 865bb27..7aa8731 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -1,5 +1,5 @@ backoff==1.11.1 docker-compose==1.29.2 docker==5.0.3 -pytest==7.1.1 +pytest==7.1.2 requests==2.27.1