From a5566f5e8f92503bb21cc318f85834839def4ec6 Mon Sep 17 00:00:00 2001 From: Francesco Cattoni Date: Sun, 22 Oct 2023 00:34:32 +0200 Subject: [PATCH 01/58] Added support for grpcs protocol --- nginx.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nginx.tmpl b/nginx.tmpl index fb0766be4..c108fa2a4 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -215,6 +215,8 @@ {{- end }} {{- else if eq .Proto "grpc" }} grpc_pass {{ trim .Proto }}://{{ trim .Upstream }}; + {{- else if eq .Proto "grpcs" }} + grpc_pass {{ trim .Proto }}://{{ trim .Upstream }}; {{- else }} proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}{{ trim .Dest }}; set $upstream_keepalive {{ if $keepalive }}true{{ else }}false{{ end }}; From 099ac04576e0692f90dca8be6ec81c68645565b1 Mon Sep 17 00:00:00 2001 From: patrickdk Date: Wed, 12 Jul 2023 23:44:40 +0200 Subject: [PATCH 02/58] feat: add new SSL policies --- README.md | 2 +- nginx.tmpl | 35 +++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 30bf5914a..e21d2331e 100644 --- a/README.md +++ b/README.md @@ -347,7 +347,7 @@ The default SSL cipher configuration is based on the [Mozilla intermediate profi If you don't require backward compatibility, you can use the [Mozilla modern profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) profile instead by including the environment variable `SSL_POLICY=Mozilla-Modern` to the nginx-proxy container or to your container. This profile is compatible with clients back to Firefox 63, Android 10.0, Chrome 70, Edge 75, Java 11, OpenSSL 1.1.1, Opera 57, and Safari 12.1. Note that this profile is **not** compatible with any version of Internet Explorer. -Other policies available through the `SSL_POLICY` environment variable are [`Mozilla-Old`](https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility) and the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) `AWS-TLS-1-2-2017-01`, `AWS-TLS-1-1-2017-01`, `AWS-2016-08`, `AWS-2015-05`, `AWS-2015-03` and `AWS-2015-02`. +Other policies available through the `SSL_POLICY` environment variable are [`Mozilla-Old`](https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility) and the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) `AWS-FS-1-2-Res-2020-10`, `AWS-FS-1-2-Res-2019-08`, `AWS-FS-1-2-2019-08`, `AWS-FS-1-1-2019-08`, `AWS-FS-2018-06`, `AWS-TLS-1-2-Ext-2018-06`, `AWS-TLS-1-2-2017-01`, `AWS-TLS-1-1-2017-01`, `AWS-2016-08`, `AWS-2015-05`, `AWS-2015-03` and `AWS-2015-02`. Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibility but this container provides a 4096 bits key. The [Diffie-Hellman Groups](#diffie-hellman-groups) section details different methods of bypassing this, either globally or per virtual-host. diff --git a/nginx.tmpl b/nginx.tmpl index db2d54b6d..aa46b2d56 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -144,12 +144,11 @@ ssl_protocols TLSv1.3; {{- /* * nginx currently lacks ability to choose ciphers in TLS 1.3 in - * configuration; see https://trac.nginx.org/nginx/ticket/1529. A - * possible workaround can be modify /etc/ssl/openssl.cnf to change - * it globally (see - * https://trac.nginx.org/nginx/ticket/1529#comment:12). Explicitly - * set ngnix default value in order to allow single servers to - * override the global http value. + * configuration, see https://trac.nginx.org/nginx/ticket/1529. + * A possible workaround can be modify /etc/ssl/openssl.cnf to change + * it globally (see https://trac.nginx.org/nginx/ticket/1529#comment:12). + * Explicitly set nginx default value in order to allow single servers + * to override the global http value. */}} ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers off; @@ -161,6 +160,30 @@ ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA'; ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-FS-1-2-Res-2020-10" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-FS-1-2-Res-2019-08" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-FS-1-2-2019-08" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-FS-1-1-2019-08" }} + ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-FS-2018-06" }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS-1-2-Ext-2018-06" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS-1-2-2017-01" }} ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; From 1535227c783164480cb919c35d16367e5f8b8794 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Wed, 12 Jul 2023 23:57:28 +0200 Subject: [PATCH 03/58] docs: up to date link to AWS ELB SSL policies --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e21d2331e..2dc1f649d 100644 --- a/README.md +++ b/README.md @@ -347,7 +347,7 @@ The default SSL cipher configuration is based on the [Mozilla intermediate profi If you don't require backward compatibility, you can use the [Mozilla modern profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) profile instead by including the environment variable `SSL_POLICY=Mozilla-Modern` to the nginx-proxy container or to your container. This profile is compatible with clients back to Firefox 63, Android 10.0, Chrome 70, Edge 75, Java 11, OpenSSL 1.1.1, Opera 57, and Safari 12.1. Note that this profile is **not** compatible with any version of Internet Explorer. -Other policies available through the `SSL_POLICY` environment variable are [`Mozilla-Old`](https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility) and the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) `AWS-FS-1-2-Res-2020-10`, `AWS-FS-1-2-Res-2019-08`, `AWS-FS-1-2-2019-08`, `AWS-FS-1-1-2019-08`, `AWS-FS-2018-06`, `AWS-TLS-1-2-Ext-2018-06`, `AWS-TLS-1-2-2017-01`, `AWS-TLS-1-1-2017-01`, `AWS-2016-08`, `AWS-2015-05`, `AWS-2015-03` and `AWS-2015-02`. +Other policies available through the `SSL_POLICY` environment variable are [`Mozilla-Old`](https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility) and the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies) `AWS-FS-1-2-Res-2020-10`, `AWS-FS-1-2-Res-2019-08`, `AWS-FS-1-2-2019-08`, `AWS-FS-1-1-2019-08`, `AWS-FS-2018-06`, `AWS-TLS-1-2-Ext-2018-06`, `AWS-TLS-1-2-2017-01`, `AWS-TLS-1-1-2017-01`, `AWS-2016-08`, `AWS-2015-05`, `AWS-2015-03` and `AWS-2015-02`. Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibility but this container provides a 4096 bits key. The [Diffie-Hellman Groups](#diffie-hellman-groups) section details different methods of bypassing this, either globally or per virtual-host. From 34655618a6923a6d3db6fd8de611b1aff0b8b960 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 8 Dec 2023 16:43:27 +0100 Subject: [PATCH 04/58] docs: cleanup SSL policies section --- README.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2dc1f649d..3d7ec446e 100644 --- a/README.md +++ b/README.md @@ -347,7 +347,80 @@ The default SSL cipher configuration is based on the [Mozilla intermediate profi If you don't require backward compatibility, you can use the [Mozilla modern profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) profile instead by including the environment variable `SSL_POLICY=Mozilla-Modern` to the nginx-proxy container or to your container. This profile is compatible with clients back to Firefox 63, Android 10.0, Chrome 70, Edge 75, Java 11, OpenSSL 1.1.1, Opera 57, and Safari 12.1. Note that this profile is **not** compatible with any version of Internet Explorer. -Other policies available through the `SSL_POLICY` environment variable are [`Mozilla-Old`](https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility) and the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies) `AWS-FS-1-2-Res-2020-10`, `AWS-FS-1-2-Res-2019-08`, `AWS-FS-1-2-2019-08`, `AWS-FS-1-1-2019-08`, `AWS-FS-2018-06`, `AWS-TLS-1-2-Ext-2018-06`, `AWS-TLS-1-2-2017-01`, `AWS-TLS-1-1-2017-01`, `AWS-2016-08`, `AWS-2015-05`, `AWS-2015-03` and `AWS-2015-02`. +Complete list of policies available through the `SSL_POLICY` environment variable, including the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies) and [AWS Classic ELB security policies](https://docs.aws.amazon.com/fr_fr/elasticloadbalancing/latest/classic/elb-security-policy-table.html): + +
+ Mozilla policies + +
+
+ AWS ELB FS supported policies +
    +
  • + AWS-FS-1-2-Res-2020-10 +
  • +
  • + AWS-FS-1-2-Res-2019-08 +
  • +
  • + AWS-FS-1-2-2019-08 +
  • +
  • + AWS-FS-1-1-2019-08 +
  • +
  • + AWS-FS-2018-06 +
  • +
+
+
+ AWS ELB TLS 1.0 - 1.2 security policies +
    +
  • + AWS-TLS-1-2-Ext-2018-06 +
  • +
  • + AWS-TLS-1-2-2017-01 +
  • +
  • + AWS-TLS-1-1-2017-01 +
  • +
  • + AWS-2016-08 +
  • +
+
+
+ AWS Classic ELB security policies +
    +
  • + AWS-2015-05 +
  • +
  • + AWS-2015-03 +
  • +
  • + AWS-2015-02 +
  • +
+
+
Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibility but this container provides a 4096 bits key. The [Diffie-Hellman Groups](#diffie-hellman-groups) section details different methods of bypassing this, either globally or per virtual-host. From 664ba246fd333e8d3ee8a7b59eabc172d6b9ca5d Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 8 Dec 2023 16:44:26 +0100 Subject: [PATCH 05/58] fix: remove unsupported TLSv1.3 from new AWS SSL policies --- nginx.tmpl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index aa46b2d56..7ff31ef29 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -161,27 +161,27 @@ ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-FS-1-2-Res-2020-10" }} - ssl_protocols TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-FS-1-2-Res-2019-08" }} - ssl_protocols TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-FS-1-2-2019-08" }} - ssl_protocols TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-FS-1-1-2019-08" }} - ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-FS-2018-06" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS-1-2-Ext-2018-06" }} - ssl_protocols TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS-1-2-2017-01" }} From 99aa94aa32023f278c88d24cd14ec6f1e853530a Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 8 Dec 2023 16:53:27 +0100 Subject: [PATCH 06/58] docs: HTML anchors fix --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3d7ec446e..a98406961 100644 --- a/README.md +++ b/README.md @@ -353,17 +353,17 @@ Complete list of policies available through the `SSL_POLICY` environment variabl Mozilla policies
  • - + Mozilla-Modern
  • - + Mozilla-Intermediate
  • - + Mozilla-Old
  • From ec0d908a4482ab3681d93b058889a0d8e3278d29 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 8 Dec 2023 17:59:26 +0100 Subject: [PATCH 07/58] feat: add AWS TLS 1.3 security policies --- README.md | 26 ++++++++++++++++++++++++++ nginx.tmpl | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a98406961..71c324ef9 100644 --- a/README.md +++ b/README.md @@ -369,6 +369,32 @@ Complete list of policies available through the `SSL_POLICY` environment variabl
+
+ AWS ELB TLS 1.3 security policies +
    +
  • + AWS-TLS13-1-3-2021-06 +
  • +
  • + AWS-TLS13-1-2-2021-06 +
  • +
  • + AWS-TLS13-1-2-Res-2021-06 +
  • +
  • + AWS-TLS13-1-2-Ext1-2021-06 +
  • +
  • + AWS-TLS13-1-2-Ext2-2021-06 +
  • +
  • + AWS-TLS13-1-1-2021-06 +
  • +
  • + AWS-TLS13-1-0-2021-06 +
  • +
+
AWS ELB FS supported policies
    diff --git a/nginx.tmpl b/nginx.tmpl index 7ff31ef29..eb64b6a5b 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -160,6 +160,34 @@ ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA'; ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS13-1-3-2021-06" }} + ssl_protocols TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS13-1-2-2021-06" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS13-1-2-Res-2021-06" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS13-1-2-Ext1-2021-06" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS13-1-2-Ext2-2021-06" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS13-1-1-2021-06" }} + ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_prefer_server_ciphers on; + {{- else if eq .ssl_policy "AWS-TLS13-1-0-2021-06" }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-FS-1-2-Res-2020-10" }} ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; @@ -185,27 +213,27 @@ ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS-1-2-2017-01" }} - ssl_protocols TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS-1-1-2017-01" }} - ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-2016-08" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-2015-05" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-2015-03" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-2015-02" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA'; ssl_prefer_server_ciphers on; {{- end }} From c6868ed6be0b6371067c204f6ec26dcd96a1f2c2 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 8 Dec 2023 22:06:07 +0100 Subject: [PATCH 08/58] fix: SSL cipher suites / TLSv1.3 --- nginx.tmpl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index eb64b6a5b..75087dc61 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -162,31 +162,32 @@ ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-3-2021-06" }} ssl_protocols TLSv1.3; - ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256'; + ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384; + ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-2-2021-06" }} ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-2-Res-2021-06" }} ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-2-Ext1-2021-06" }} ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-2-Ext2-2021-06" }} ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-1-2021-06" }} ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-0-2021-06" }} ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-FS-1-2-Res-2020-10" }} ssl_protocols TLSv1.2; From 4c556290f9ec21e4648ed85a1bb7f89cdcef26c2 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Fri, 8 Dec 2023 22:41:29 +0100 Subject: [PATCH 09/58] fix: enforce TLSv1.3 on Mozilla-Modern SSL policy --- nginx.tmpl | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 75087dc61..f830fd2ee 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -142,15 +142,12 @@ {{- define "ssl_policy" }} {{- if eq .ssl_policy "Mozilla-Modern" }} ssl_protocols TLSv1.3; - {{- /* - * nginx currently lacks ability to choose ciphers in TLS 1.3 in - * configuration, see https://trac.nginx.org/nginx/ticket/1529. - * A possible workaround can be modify /etc/ssl/openssl.cnf to change - * it globally (see https://trac.nginx.org/nginx/ticket/1529#comment:12). - * Explicitly set nginx default value in order to allow single servers - * to override the global http value. - */}} - ssl_ciphers HIGH:!aNULL:!MD5; + {{- /* + * This ssl_ciphers directive is not used but necessary to get TLSv1.3 only. + * see https://serverfault.com/questions/1023766/nginx-with-only-tls1-3-cipher-suites + */}} + ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384; + ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256; ssl_prefer_server_ciphers off; {{- else if eq .ssl_policy "Mozilla-Intermediate" }} ssl_protocols TLSv1.2 TLSv1.3; @@ -162,6 +159,10 @@ ssl_prefer_server_ciphers on; {{- else if eq .ssl_policy "AWS-TLS13-1-3-2021-06" }} ssl_protocols TLSv1.3; + {{- /* + * This ssl_ciphers directive is not used but necessary to get TLSv1.3 only. + * see https://serverfault.com/questions/1023766/nginx-with-only-tls1-3-cipher-suites + */}} ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384; ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256; ssl_prefer_server_ciphers on; From c06593bdcb7be07b41cf5c0624155ccdfa87d5ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 04:09:41 +0000 Subject: [PATCH 10/58] ci: bump actions/setup-python from 4 to 5 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2d8db9236..36e6273e6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python 3.9 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.9 From b5cac063058c195e87ed87f8f70e1a56111f7aef Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 11 Dec 2023 13:54:28 +0100 Subject: [PATCH 11/58] ci: remove python docker-compose --- README.md | 6 +++--- test/README.md | 6 +++--- test/conftest.py | 16 ++++++++-------- test/pytest.sh | 4 ++-- test/requirements/python-requirements.txt | 1 - test/test_wildcard_host.yml | 2 +- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 71c324ef9..6ff07f0bf 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ services: ``` ```console -docker-compose up +docker compose up curl -H "Host: whoami.example" localhost ``` @@ -259,10 +259,10 @@ nginx-proxy can also be run as two separate containers using the [nginxproxy/doc You may want to do this to prevent having the docker socket bound to a publicly exposed container service. -You can demo this pattern with docker-compose: +You can demo this pattern with docker compose: ```console -docker-compose --file docker-compose-separate-containers.yml up +docker compose --file docker-compose-separate-containers.yml up curl -H "Host: whoami.example" localhost ``` diff --git a/test/README.md b/test/README.md index 99d16dbc9..5a93e1bb1 100644 --- a/test/README.md +++ b/test/README.md @@ -48,11 +48,11 @@ This test suite uses [pytest](http://doc.pytest.org/en/latest/). The [conftest.p When using the `docker_compose` fixture in a test, pytest will try to find a yml file named after your test module filename. For instance, if your test module is `test_example.py`, then the `docker_compose` fixture will try to load a `test_example.yml` [docker compose file](https://docs.docker.com/compose/compose-file/). -Once the docker compose file found, the fixture will remove all containers, run `docker-compose up`, and finally your test will be executed. +Once the docker compose file found, the fixture will remove all containers, run `docker compose up`, and finally your test will be executed. -The fixture will run the _docker-compose_ command with the `-f` option to load the given compose file. So you can test your docker compose file syntax by running it yourself with: +The fixture will run the _docker compose_ command with the `-f` option to load the given compose file. So you can test your docker compose file syntax by running it yourself with: - docker-compose -f test_example.yml up -d + docker compose -f test_example.yml up -d In the case you are running pytest from within a docker container, the `docker_compose` fixture will make sure the container running pytest is attached to all docker networks. That way, your test will be able to reach any of them. diff --git a/test/conftest.py b/test/conftest.py index f73b7c0a2..938be6bcd 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -301,19 +301,19 @@ def get_nginx_conf_from_container(container): def docker_compose_up(compose_file='docker-compose.yml'): - logging.info(f'docker-compose -f {compose_file} up -d') + logging.info(f'docker compose -f {compose_file} up -d') try: - subprocess.check_output(shlex.split(f'docker-compose -f {compose_file} up -d'), stderr=subprocess.STDOUT) + subprocess.check_output(shlex.split(f'docker compose -f {compose_file} up -d'), stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - pytest.fail(f"Error while runninng 'docker-compose -f {compose_file} up -d':\n{e.output}", pytrace=False) + pytest.fail(f"Error while runninng 'docker compose -f {compose_file} up -d':\n{e.output}", pytrace=False) def docker_compose_down(compose_file='docker-compose.yml'): - logging.info(f'docker-compose -f {compose_file} down -v') + logging.info(f'docker compose -f {compose_file} down -v') try: - subprocess.check_output(shlex.split(f'docker-compose -f {compose_file} down -v'), stderr=subprocess.STDOUT) + subprocess.check_output(shlex.split(f'docker compose -f {compose_file} down -v'), stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - pytest.fail(f"Error while runninng 'docker-compose -f {compose_file} down -v':\n{e.output}", pytrace=False) + pytest.fail(f"Error while runninng 'docker compose -f {compose_file} down -v':\n{e.output}", pytrace=False) def wait_for_nginxproxy_to_be_ready(): @@ -333,7 +333,7 @@ def wait_for_nginxproxy_to_be_ready(): @pytest.fixture def docker_compose_file(request): - """Fixture naming the docker-compose file to consider. + """Fixture naming the docker compose file to consider. If a YAML file exists with the same name as the test module (with the `.py` extension replaced with `.yml` or `.yaml`), use that. Otherwise, use `docker-compose.yml` in the same directory @@ -354,7 +354,7 @@ def docker_compose_file(request): docker_compose_file = default_file if not os.path.isfile(docker_compose_file): - logging.error("Could not find any docker-compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__)) + logging.error("Could not find any docker compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__)) logging.debug(f"using docker compose file {docker_compose_file}") return docker_compose_file diff --git a/test/pytest.sh b/test/pytest.sh index 19a81881f..9cbe75017 100755 --- a/test/pytest.sh +++ b/test/pytest.sh @@ -19,8 +19,8 @@ docker build --pull -t nginx-proxy-tester \ "${TESTDIR}/requirements" \ || exit 1 -# 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. +# 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 --name "nginx-proxy-pytest" \ --volume "/var/run/docker.sock:/var/run/docker.sock" \ --volume "${DIR}:${DIR}" \ diff --git a/test/requirements/python-requirements.txt b/test/requirements/python-requirements.txt index 15182fd2b..079a74e64 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -1,5 +1,4 @@ backoff==2.2.1 -docker-compose==1.29.2 docker==6.1.3 pytest==7.4.3 requests==2.31.0 diff --git a/test/test_wildcard_host.yml b/test/test_wildcard_host.yml index b745e3103..cd6687393 100644 --- a/test/test_wildcard_host.yml +++ b/test/test_wildcard_host.yml @@ -28,7 +28,7 @@ web4: - "84" environment: WEB_PORTS: "84" - VIRTUAL_HOST: ~^web4\..*\.nginx-proxy\.regexp$$ # we need to double the `$` because of docker-compose variable interpolation + VIRTUAL_HOST: ~^web4\..*\.nginx-proxy\.regexp$$ # we need to double the `$` because of docker compose variable interpolation sut: From 060f09cfce3e7cb8da1722ebdb1300f752e5ef71 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 11 Dec 2023 14:25:04 +0100 Subject: [PATCH 12/58] ci: ensure all compose files are valid compose v2 + formatting --- docker-compose-separate-containers.yml | 3 +- docker-compose.yml | 3 +- .../test_deleted_cert/docker-compose.yml | 28 ++-- .../docker-compose.yml | 1 - test/test_DOCKER_HOST_unix_socket.yml | 42 +++--- test/test_composev2.yml | 3 +- test/test_custom/test_defaults-location.yml | 57 ++++---- test/test_custom/test_defaults.yml | 3 +- test/test_custom/test_location-per-vhost.yml | 3 +- test/test_custom/test_per-vhost.yml | 3 +- test/test_custom/test_proxy-wide.yml | 3 +- test/test_default-host.yml | 32 +++-- test/test_default-root-none.yml | 3 + test/test_dockergen/test_dockergen_v2.yml | 2 +- test/test_dockergen/test_dockergen_v3.yml | 3 +- test/test_events.yml | 11 +- test/test_fallback.data/custom-fallback.yml | 3 + test/test_fallback.data/nodefault.yml | 6 + test/test_fallback.data/nohttp-on-app.yml | 3 + .../nohttp-with-missing-cert.yml | 4 + test/test_fallback.data/nohttp.yml | 3 + test/test_fallback.data/nohttps-on-app.yml | 3 + test/test_fallback.data/nohttps.yml | 3 + test/test_fallback.data/withdefault.yml | 6 + test/test_headers/test_http.yml | 40 +++--- test/test_headers/test_https.yml | 52 +++---- .../test_http2/test_http2_global_disabled.yml | 2 + .../test_http3/test_http3_global_disabled.yml | 4 +- test/test_http3/test_http3_global_enabled.yml | 2 + test/test_http3/test_http3_vhost.yml | 2 + test/test_http_port.yml | 29 ++-- .../test_internal/test_internal-per-vhost.yml | 42 +++--- .../test_internal/test_internal-per-vpath.yml | 50 +++---- test/test_ipv6.yml | 3 +- test/test_keepalive.yml | 46 +++--- test/test_loadbalancing.yml | 2 + test/test_location-override.yml | 2 + test/test_log_format.yml | 31 ++-- test/test_multiple-hosts.yml | 24 ++-- test/test_multiple-networks.yml | 2 +- ...PORT-single-different-from-single-port.yml | 26 ++-- .../test_multiple-ports/test_VIRTUAL_PORT.yml | 29 ++-- test/test_multiple-ports/test_default-80.yml | 27 ++-- .../test_single-port-not-80.yml | 24 ++-- test/test_nominal.yml | 3 +- test/test_raw-ip-vhost.yml | 4 +- test/test_server-down/test_load-balancing.yml | 55 ++++---- test/test_server-down/test_no-server-down.yml | 25 ++-- test/test_server-down/test_server-down.yml | 27 ++-- test/test_ssl/test_dhparam.yml | 132 +++++++++--------- test/test_ssl/test_hsts.yml | 95 +++++++------ test/test_ssl/test_https_port.yml | 33 +++-- test/test_ssl/test_nohttp.yml | 28 ++-- test/test_ssl/test_nohttps.yml | 26 ++-- test/test_ssl/test_noredirect.yml | 28 ++-- test/test_ssl/test_virtual_path.yml | 48 ++++--- test/test_ssl/test_wildcard.yml | 27 ++-- .../test_default.yml | 30 ++-- .../test_disabled.yml | 34 ++--- .../test_enabled.yml | 34 ++--- .../test_predictable-name.yml | 2 +- test/test_upstream-name/test_sha1-name.yml | 2 +- test/test_vhost-empty-string.yml | 6 + test/test_vhost-in-multiple-networks.yml | 2 +- test/test_virtual-path/test_custom_conf.yml | 87 ++++++------ test/test_virtual-path/test_forwarding.yml | 35 ++--- .../test_location_precedence.yml | 71 +++++----- test/test_virtual-path/test_virtual_paths.yml | 76 +++++----- test/test_wildcard_host.yml | 66 ++++----- 69 files changed, 894 insertions(+), 752 deletions(-) diff --git a/docker-compose-separate-containers.yml b/docker-compose-separate-containers.yml index 427763282..5a6489596 100644 --- a/docker-compose-separate-containers.yml +++ b/docker-compose-separate-containers.yml @@ -1,4 +1,5 @@ -version: '2' +version: "2" + services: nginx: image: nginx diff --git a/docker-compose.yml b/docker-compose.yml index 931c364bb..809d6fa80 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,5 @@ -version: '2' +version: "2" + services: nginx-proxy: image: nginxproxy/nginx-proxy diff --git a/test/stress_tests/test_deleted_cert/docker-compose.yml b/test/stress_tests/test_deleted_cert/docker-compose.yml index a42abacad..a362e443d 100644 --- a/test/stress_tests/test_deleted_cert/docker-compose.yml +++ b/test/stress_tests/test_deleted_cert/docker-compose.yml @@ -1,15 +1,17 @@ -web: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web.nginx-proxy +version: "2" +services: + web: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web.nginx-proxy -reverseproxy: - image: nginxproxy/nginx-proxy:test - container_name: reverseproxy - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./tmp_certs:/etc/nginx/certs:ro + reverseproxy: + image: nginxproxy/nginx-proxy:test + container_name: reverseproxy + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./tmp_certs:/etc/nginx/certs:ro diff --git a/test/stress_tests/test_unreachable_network/docker-compose.yml b/test/stress_tests/test_unreachable_network/docker-compose.yml index 9666d2970..f90a441e7 100644 --- a/test/stress_tests/test_unreachable_network/docker-compose.yml +++ b/test/stress_tests/test_unreachable_network/docker-compose.yml @@ -32,4 +32,3 @@ services: environment: WEB_PORTS: 82 VIRTUAL_HOST: webB.nginx-proxy - diff --git a/test/test_DOCKER_HOST_unix_socket.yml b/test/test_DOCKER_HOST_unix_socket.yml index 15638725d..caeaa2a55 100644 --- a/test/test_DOCKER_HOST_unix_socket.yml +++ b/test/test_DOCKER_HOST_unix_socket.yml @@ -1,23 +1,25 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web1.nginx-proxy.tld +version: "2" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: 82 - VIRTUAL_HOST: web2.nginx-proxy.tld +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web1.nginx-proxy.tld + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: 82 + VIRTUAL_HOST: web2.nginx-proxy.tld -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/f00.sock:ro - environment: - DOCKER_HOST: unix:///f00.sock + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/f00.sock:ro + environment: + DOCKER_HOST: unix:///f00.sock diff --git a/test/test_composev2.yml b/test/test_composev2.yml index dff434c63..3c36022b5 100644 --- a/test/test_composev2.yml +++ b/test/test_composev2.yml @@ -1,4 +1,5 @@ -version: '2' +version: "2" + services: nginx-proxy: image: nginxproxy/nginx-proxy:test diff --git a/test/test_custom/test_defaults-location.yml b/test/test_custom/test_defaults-location.yml index 195d232fc..9a3ab44f3 100644 --- a/test/test_custom/test_defaults-location.yml +++ b/test/test_custom/test_defaults-location.yml @@ -1,30 +1,33 @@ -nginx-proxy: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/default_location:ro - - ./my_custom_proxy_settings_bar.conf:/etc/nginx/vhost.d/web3.nginx-proxy.example_location:ro +version: "2" -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web1.nginx-proxy.example +services: + nginx-proxy: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/default_location:ro + - ./my_custom_proxy_settings_bar.conf:/etc/nginx/vhost.d/web3.nginx-proxy.example_location:ro -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: 82 - VIRTUAL_HOST: web2.nginx-proxy.example + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web1.nginx-proxy.example -web3: - image: web - expose: - - "83" - environment: - WEB_PORTS: 83 - VIRTUAL_HOST: web3.nginx-proxy.example + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: 82 + VIRTUAL_HOST: web2.nginx-proxy.example + + web3: + image: web + expose: + - "83" + environment: + WEB_PORTS: 83 + VIRTUAL_HOST: web3.nginx-proxy.example diff --git a/test/test_custom/test_defaults.yml b/test/test_custom/test_defaults.yml index 2983e25f0..d6a959a48 100644 --- a/test/test_custom/test_defaults.yml +++ b/test/test_custom/test_defaults.yml @@ -1,4 +1,5 @@ -version: '2' +version: "2" + services: nginx-proxy: image: nginxproxy/nginx-proxy:test diff --git a/test/test_custom/test_location-per-vhost.yml b/test/test_custom/test_location-per-vhost.yml index 6bf69f9d0..52943086e 100644 --- a/test/test_custom/test_location-per-vhost.yml +++ b/test/test_custom/test_location-per-vhost.yml @@ -1,4 +1,5 @@ -version: '2' +version: "2" + services: nginx-proxy: image: nginxproxy/nginx-proxy:test diff --git a/test/test_custom/test_per-vhost.yml b/test/test_custom/test_per-vhost.yml index e7e50b49b..63d33b2b1 100644 --- a/test/test_custom/test_per-vhost.yml +++ b/test/test_custom/test_per-vhost.yml @@ -1,4 +1,5 @@ -version: '2' +version: "2" + services: nginx-proxy: image: nginxproxy/nginx-proxy:test diff --git a/test/test_custom/test_proxy-wide.yml b/test/test_custom/test_proxy-wide.yml index 0c4a2a0f5..1322bcde7 100644 --- a/test/test_custom/test_proxy-wide.yml +++ b/test/test_custom/test_proxy-wide.yml @@ -1,4 +1,5 @@ -version: '2' +version: "2" + services: nginx-proxy: image: nginxproxy/nginx-proxy:test diff --git a/test/test_default-host.yml b/test/test_default-host.yml index 2cb94d97c..405bb081a 100644 --- a/test/test_default-host.yml +++ b/test/test_default-host.yml @@ -1,17 +1,19 @@ -# GIVEN a webserver with VIRTUAL_HOST set to web1.tld -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web1.tld +version: "2" +services: + # GIVEN a webserver with VIRTUAL_HOST set to web1.tld + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web1.tld -# WHEN nginx-proxy runs with DEFAULT_HOST set to web1.tld -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - environment: - DEFAULT_HOST: web1.tld + # WHEN nginx-proxy runs with DEFAULT_HOST set to web1.tld + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + DEFAULT_HOST: web1.tld diff --git a/test/test_default-root-none.yml b/test/test_default-root-none.yml index 309d2ab3e..f0172e8f5 100644 --- a/test/test_default-root-none.yml +++ b/test/test_default-root-none.yml @@ -1,3 +1,5 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test @@ -5,6 +7,7 @@ services: - /var/run/docker.sock:/tmp/docker.sock:ro environment: DEFAULT_ROOT: none + web: image: web expose: diff --git a/test/test_dockergen/test_dockergen_v2.yml b/test/test_dockergen/test_dockergen_v2.yml index 36ee1c169..f98992f20 100644 --- a/test/test_dockergen/test_dockergen_v2.yml +++ b/test/test_dockergen/test_dockergen_v2.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" services: nginx: diff --git a/test/test_dockergen/test_dockergen_v3.yml b/test/test_dockergen/test_dockergen_v3.yml index 8b0411caa..7e4aef8c1 100644 --- a/test/test_dockergen/test_dockergen_v3.yml +++ b/test/test_dockergen/test_dockergen_v3.yml @@ -1,4 +1,5 @@ -version: '3' +version: "3" + services: nginx: image: nginx diff --git a/test/test_events.yml b/test/test_events.yml index 260529e72..ac27e1d0c 100644 --- a/test/test_events.yml +++ b/test/test_events.yml @@ -1,4 +1,7 @@ -nginxproxy: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro +version: "2" + +services: + nginxproxy: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_fallback.data/custom-fallback.yml b/test/test_fallback.data/custom-fallback.yml index bc44b1188..a15044181 100644 --- a/test/test_fallback.data/custom-fallback.yml +++ b/test/test_fallback.data/custom-fallback.yml @@ -1,9 +1,12 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - ./custom-fallback.conf:/etc/nginx/conf.d/zzz-custom-fallback.conf:ro + http-only: image: web expose: diff --git a/test/test_fallback.data/nodefault.yml b/test/test_fallback.data/nodefault.yml index ecd43591a..6397a0bc6 100644 --- a/test/test_fallback.data/nodefault.yml +++ b/test/test_fallback.data/nodefault.yml @@ -1,9 +1,12 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - ./nodefault.certs:/etc/nginx/certs:ro + https-and-http: image: web expose: @@ -11,6 +14,7 @@ services: environment: WEB_PORTS: "81" VIRTUAL_HOST: https-and-http.nginx-proxy.test + https-only: image: web expose: @@ -19,6 +23,7 @@ services: WEB_PORTS: "82" VIRTUAL_HOST: https-only.nginx-proxy.test HTTPS_METHOD: nohttp + http-only: image: web expose: @@ -27,6 +32,7 @@ services: WEB_PORTS: "83" VIRTUAL_HOST: http-only.nginx-proxy.test HTTPS_METHOD: nohttps + missing-cert: image: web expose: diff --git a/test/test_fallback.data/nohttp-on-app.yml b/test/test_fallback.data/nohttp-on-app.yml index d81c9ca64..b6ca82a19 100644 --- a/test/test_fallback.data/nohttp-on-app.yml +++ b/test/test_fallback.data/nohttp-on-app.yml @@ -1,3 +1,5 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test @@ -6,6 +8,7 @@ services: - ./withdefault.certs:/etc/nginx/certs:ro environment: HTTPS_METHOD: redirect + https-only: image: web expose: diff --git a/test/test_fallback.data/nohttp-with-missing-cert.yml b/test/test_fallback.data/nohttp-with-missing-cert.yml index 3593a32c1..70ece7b77 100644 --- a/test/test_fallback.data/nohttp-with-missing-cert.yml +++ b/test/test_fallback.data/nohttp-with-missing-cert.yml @@ -1,3 +1,5 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test @@ -6,6 +8,7 @@ services: - ./withdefault.certs:/etc/nginx/certs:ro environment: HTTPS_METHOD: nohttp + https-only: image: web expose: @@ -13,6 +16,7 @@ services: environment: WEB_PORTS: "82" VIRTUAL_HOST: https-only.nginx-proxy.test + missing-cert: image: web expose: diff --git a/test/test_fallback.data/nohttp.yml b/test/test_fallback.data/nohttp.yml index 3ed0c0e96..9d47d51a3 100644 --- a/test/test_fallback.data/nohttp.yml +++ b/test/test_fallback.data/nohttp.yml @@ -1,3 +1,5 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test @@ -6,6 +8,7 @@ services: - ./withdefault.certs:/etc/nginx/certs:ro environment: HTTPS_METHOD: nohttp + https-only: image: web expose: diff --git a/test/test_fallback.data/nohttps-on-app.yml b/test/test_fallback.data/nohttps-on-app.yml index 690d6562e..966154cf9 100644 --- a/test/test_fallback.data/nohttps-on-app.yml +++ b/test/test_fallback.data/nohttps-on-app.yml @@ -1,3 +1,5 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test @@ -5,6 +7,7 @@ services: - /var/run/docker.sock:/tmp/docker.sock:ro environment: HTTPS_METHOD: redirect + http-only: image: web expose: diff --git a/test/test_fallback.data/nohttps.yml b/test/test_fallback.data/nohttps.yml index f07ddf946..c73349247 100644 --- a/test/test_fallback.data/nohttps.yml +++ b/test/test_fallback.data/nohttps.yml @@ -1,3 +1,5 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test @@ -5,6 +7,7 @@ services: - /var/run/docker.sock:/tmp/docker.sock:ro environment: HTTPS_METHOD: nohttps + http-only: image: web expose: diff --git a/test/test_fallback.data/withdefault.yml b/test/test_fallback.data/withdefault.yml index 00f7ee7a0..46ab1267a 100644 --- a/test/test_fallback.data/withdefault.yml +++ b/test/test_fallback.data/withdefault.yml @@ -1,9 +1,12 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - ./withdefault.certs:/etc/nginx/certs:ro + https-and-http: image: web expose: @@ -11,6 +14,7 @@ services: environment: WEB_PORTS: "81" VIRTUAL_HOST: https-and-http.nginx-proxy.test + https-only: image: web expose: @@ -19,6 +23,7 @@ services: WEB_PORTS: "82" VIRTUAL_HOST: https-only.nginx-proxy.test HTTPS_METHOD: nohttp + http-only: image: web expose: @@ -27,6 +32,7 @@ services: WEB_PORTS: "83" VIRTUAL_HOST: http-only.nginx-proxy.test HTTPS_METHOD: nohttps + missing-cert: image: web expose: diff --git a/test/test_headers/test_http.yml b/test/test_headers/test_http.yml index 93795dc60..fa5984028 100644 --- a/test/test_headers/test_http.yml +++ b/test/test_headers/test_http.yml @@ -1,22 +1,24 @@ -web: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: web.nginx-proxy.tld +version: "2" -web-server-tokens-off: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld - SERVER_TOKENS: "off" +services: + web: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: web.nginx-proxy.tld + web-server-tokens-off: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld + SERVER_TOKENS: "off" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_headers/test_https.yml b/test/test_headers/test_https.yml index 49dcec456..0300d4386 100644 --- a/test/test_headers/test_https.yml +++ b/test/test_headers/test_https.yml @@ -1,28 +1,30 @@ -web: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: web.nginx-proxy.tld +version: "2" -web-server-tokens-off: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld - SERVER_TOKENS: "off" +services: + web: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: web.nginx-proxy.tld + web-server-tokens-off: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld + SERVER_TOKENS: "off" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/default.crt:ro - - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/default.key:ro - - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro - - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro - - ./certs/web-server-tokens-off.nginx-proxy.tld.crt:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.crt:ro - - ./certs/web-server-tokens-off.nginx-proxy.tld.key:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.key:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/default.crt:ro + - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/default.key:ro + - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro + - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro + - ./certs/web-server-tokens-off.nginx-proxy.tld.crt:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.crt:ro + - ./certs/web-server-tokens-off.nginx-proxy.tld.key:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.key:ro diff --git a/test/test_http2/test_http2_global_disabled.yml b/test/test_http2/test_http2_global_disabled.yml index 5dffa1972..8fd3cde63 100644 --- a/test/test_http2/test_http2_global_disabled.yml +++ b/test/test_http2/test_http2_global_disabled.yml @@ -1,3 +1,5 @@ +version: "2" + services: http2-global-disabled: image: web diff --git a/test/test_http3/test_http3_global_disabled.yml b/test/test_http3/test_http3_global_disabled.yml index 66530a4bc..482a5eaea 100644 --- a/test/test_http3/test_http3_global_disabled.yml +++ b/test/test_http3/test_http3_global_disabled.yml @@ -1,3 +1,5 @@ +version: "2" + services: http3-global-disabled: image: web @@ -12,4 +14,4 @@ services: volumes: - /var/run/docker.sock:/tmp/docker.sock:ro #environment: - #ENABLE_HTTP3: "false" #Disabled by default + #ENABLE_HTTP3: "false" #Disabled by default diff --git a/test/test_http3/test_http3_global_enabled.yml b/test/test_http3/test_http3_global_enabled.yml index 082546929..1cd40e0a0 100644 --- a/test/test_http3/test_http3_global_enabled.yml +++ b/test/test_http3/test_http3_global_enabled.yml @@ -1,3 +1,5 @@ +version: "2" + services: http3-global-enabled: image: web diff --git a/test/test_http3/test_http3_vhost.yml b/test/test_http3/test_http3_vhost.yml index 1d5cdf26e..345bb30e5 100644 --- a/test/test_http3/test_http3_vhost.yml +++ b/test/test_http3/test_http3_vhost.yml @@ -1,3 +1,5 @@ +version: "2" + services: http3-vhost-enabled: image: web diff --git a/test/test_http_port.yml b/test/test_http_port.yml index 72f142fae..a346982c3 100644 --- a/test/test_http_port.yml +++ b/test/test_http_port.yml @@ -1,14 +1,17 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "*.nginx-proxy.tld" +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - environment: - HTTP_PORT: 8080 \ No newline at end of file +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "*.nginx-proxy.tld" + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + HTTP_PORT: 8080 diff --git a/test/test_internal/test_internal-per-vhost.yml b/test/test_internal/test_internal-per-vhost.yml index 3763723a0..cc67c2240 100644 --- a/test/test_internal/test_internal-per-vhost.yml +++ b/test/test_internal/test_internal-per-vhost.yml @@ -1,23 +1,25 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web1.nginx-proxy.example - NETWORK_ACCESS: internal +version: "2" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: 82 - VIRTUAL_HOST: web2.nginx-proxy.example +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web1.nginx-proxy.example + NETWORK_ACCESS: internal -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./network_internal.conf:/etc/nginx/network_internal.conf:ro + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: 82 + VIRTUAL_HOST: web2.nginx-proxy.example + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock: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 3cc4a05af..35e92f051 100644 --- a/test/test_internal/test_internal-per-vpath.yml +++ b/test/test_internal/test_internal-per-vpath.yml @@ -1,27 +1,29 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: nginx-proxy.example - VIRTUAL_PATH: /web1/ - VIRTUAL_DEST: / - NETWORK_ACCESS: internal +version: "2" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: 82 - VIRTUAL_HOST: nginx-proxy.example - VIRTUAL_PATH: /web2/ - VIRTUAL_DEST: / +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: nginx-proxy.example + VIRTUAL_PATH: /web1/ + VIRTUAL_DEST: / + NETWORK_ACCESS: internal -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./network_internal.conf:/etc/nginx/network_internal.conf:ro + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: 82 + VIRTUAL_HOST: nginx-proxy.example + VIRTUAL_PATH: /web2/ + VIRTUAL_DEST: / + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./network_internal.conf:/etc/nginx/network_internal.conf:ro diff --git a/test/test_ipv6.yml b/test/test_ipv6.yml index 4dce515d3..d5fec9b40 100644 --- a/test/test_ipv6.yml +++ b/test/test_ipv6.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" networks: net1: @@ -28,7 +28,6 @@ services: networks: - net1 - sut: image: nginxproxy/nginx-proxy:test volumes: diff --git a/test/test_keepalive.yml b/test/test_keepalive.yml index 541b69dec..62f5b252f 100644 --- a/test/test_keepalive.yml +++ b/test/test_keepalive.yml @@ -1,25 +1,27 @@ -keepalive-disabled: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: keepalive-disabled.nginx-proxy.test +version: "2" -keepalive-enabled: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: keepalive-enabled.nginx-proxy.test - labels: - com.github.nginx-proxy.nginx-proxy.keepalive: "64" +services: + keepalive-disabled: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: keepalive-disabled.nginx-proxy.test + keepalive-enabled: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: keepalive-enabled.nginx-proxy.test + labels: + com.github.nginx-proxy.nginx-proxy.keepalive: "64" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - environment: - HTTPS_METHOD: nohttps + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + HTTPS_METHOD: nohttps diff --git a/test/test_loadbalancing.yml b/test/test_loadbalancing.yml index b8f42eb67..72155fb11 100644 --- a/test/test_loadbalancing.yml +++ b/test/test_loadbalancing.yml @@ -1,3 +1,5 @@ +version: "2" + services: loadbalance-hash: image: web diff --git a/test/test_location-override.yml b/test/test_location-override.yml index f36b206a7..9ba4eb82b 100644 --- a/test/test_location-override.yml +++ b/test/test_location-override.yml @@ -1,3 +1,5 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test diff --git a/test/test_log_format.yml b/test/test_log_format.yml index ef3bbf624..2a32e3d00 100644 --- a/test/test_log_format.yml +++ b/test/test_log_format.yml @@ -1,15 +1,18 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: nginx-proxy.test +version: "2" -sut: - container_name: sut - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - environment: - LOG_FORMAT: "$$remote_addr - $$remote_user [$$time_local] \"$$request\" $$status $$body_bytes_sent \"$$http_referer\" \"$$http_user_agent\" request_time=$$request_time $$upstream_response_time" +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: nginx-proxy.test + + sut: + container_name: sut + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + LOG_FORMAT: '$$remote_addr - $$remote_user [$$time_local] "$$request" $$status $$body_bytes_sent "$$http_referer" "$$http_user_agent" request_time=$$request_time $$upstream_response_time' diff --git a/test/test_multiple-hosts.yml b/test/test_multiple-hosts.yml index b72da83d7..832aac4cf 100644 --- a/test/test_multiple-hosts.yml +++ b/test/test_multiple-hosts.yml @@ -1,13 +1,15 @@ -web: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: webA.nginx-proxy.tld,webB.nginx-proxy.tld +version: "2" +services: + web: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: webA.nginx-proxy.tld,webB.nginx-proxy.tld -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_multiple-networks.yml b/test/test_multiple-networks.yml index 1247cb314..3e34b481e 100644 --- a/test/test_multiple-networks.yml +++ b/test/test_multiple-networks.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" networks: net1: {} diff --git a/test/test_multiple-ports/test_VIRTUAL_PORT-single-different-from-single-port.yml b/test/test_multiple-ports/test_VIRTUAL_PORT-single-different-from-single-port.yml index dff62128d..ba58d4ec1 100644 --- a/test/test_multiple-ports/test_VIRTUAL_PORT-single-different-from-single-port.yml +++ b/test/test_multiple-ports/test_VIRTUAL_PORT-single-different-from-single-port.yml @@ -1,14 +1,16 @@ -web: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "web.nginx-proxy.tld" - VIRTUAL_PORT: "90" +version: "2" +services: + web: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "web.nginx-proxy.tld" + VIRTUAL_PORT: "90" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_multiple-ports/test_VIRTUAL_PORT.yml b/test/test_multiple-ports/test_VIRTUAL_PORT.yml index 1a3ecaa4e..ab1af4664 100644 --- a/test/test_multiple-ports/test_VIRTUAL_PORT.yml +++ b/test/test_multiple-ports/test_VIRTUAL_PORT.yml @@ -1,14 +1,17 @@ -web: - image: web - expose: - - "80" - - "90" - environment: - WEB_PORTS: "80 90" - VIRTUAL_HOST: "web.nginx-proxy.tld" - VIRTUAL_PORT: 90 +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro +services: + web: + image: web + expose: + - "80" + - "90" + environment: + WEB_PORTS: "80 90" + VIRTUAL_HOST: "web.nginx-proxy.tld" + VIRTUAL_PORT: 90 + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_multiple-ports/test_default-80.yml b/test/test_multiple-ports/test_default-80.yml index 10047dc51..0cfdd7e62 100644 --- a/test/test_multiple-ports/test_default-80.yml +++ b/test/test_multiple-ports/test_default-80.yml @@ -1,13 +1,16 @@ -web: - image: web - expose: - - "80" - - "81" - environment: - WEB_PORTS: "80 81" - VIRTUAL_HOST: "web.nginx-proxy.tld" +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro +services: + web: + image: web + expose: + - "80" + - "81" + environment: + WEB_PORTS: "80 81" + VIRTUAL_HOST: "web.nginx-proxy.tld" + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_multiple-ports/test_single-port-not-80.yml b/test/test_multiple-ports/test_single-port-not-80.yml index 18b365507..eef4e0899 100644 --- a/test/test_multiple-ports/test_single-port-not-80.yml +++ b/test/test_multiple-ports/test_single-port-not-80.yml @@ -1,13 +1,15 @@ -web: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "web.nginx-proxy.tld" +version: "2" +services: + web: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "web.nginx-proxy.tld" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_nominal.yml b/test/test_nominal.yml index fe0203405..60678951b 100644 --- a/test/test_nominal.yml +++ b/test/test_nominal.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" networks: net1: @@ -28,7 +28,6 @@ services: networks: - net1 - sut: image: nginxproxy/nginx-proxy:test volumes: diff --git a/test/test_raw-ip-vhost.yml b/test/test_raw-ip-vhost.yml index 066dade1d..f034bdb87 100644 --- a/test/test_raw-ip-vhost.yml +++ b/test/test_raw-ip-vhost.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" networks: net1: @@ -6,7 +6,7 @@ networks: ipam: config: - subnet: 172.20.0.0/16 - - subnet: fd00::/80 + - subnet: fd00::/80 services: web1: diff --git a/test/test_server-down/test_load-balancing.yml b/test/test_server-down/test_load-balancing.yml index d420072b3..bde23d613 100644 --- a/test/test_server-down/test_load-balancing.yml +++ b/test/test_server-down/test_load-balancing.yml @@ -1,29 +1,32 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web.nginx-proxy.tld +version: "2" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: 83 - VIRTUAL_HOST: web.nginx-proxy.tld +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web.nginx-proxy.tld -web3: - image: web - expose: - - "83" - environment: - WEB_PORTS: 83 - VIRTUAL_HOST: web.nginx-proxy.tld - net: "none" + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: 83 + VIRTUAL_HOST: web.nginx-proxy.tld -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro + web3: + image: web + expose: + - "83" + environment: + WEB_PORTS: 83 + VIRTUAL_HOST: web.nginx-proxy.tld + net: "none" + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_server-down/test_no-server-down.yml b/test/test_server-down/test_no-server-down.yml index b3d46291f..cd7e5acf5 100644 --- a/test/test_server-down/test_no-server-down.yml +++ b/test/test_server-down/test_no-server-down.yml @@ -1,12 +1,15 @@ -web: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web.nginx-proxy.tld +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro +services: + web: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web.nginx-proxy.tld + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_server-down/test_server-down.yml b/test/test_server-down/test_server-down.yml index 938d26a14..d4d109a33 100644 --- a/test/test_server-down/test_server-down.yml +++ b/test/test_server-down/test_server-down.yml @@ -1,13 +1,16 @@ -web: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: web.nginx-proxy.tld - net: "none" +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro +services: + web: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: web.nginx-proxy.tld + net: "none" + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_ssl/test_dhparam.yml b/test/test_ssl/test_dhparam.yml index 505ac4cb6..456b1b3f8 100644 --- a/test/test_ssl/test_dhparam.yml +++ b/test/test_ssl/test_dhparam.yml @@ -1,73 +1,75 @@ -web5: - image: web - expose: - - "85" - environment: - WEB_PORTS: "85" - VIRTUAL_HOST: "web5.nginx-proxy.tld" +version: "2" -# 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" +services: + web5: + image: web + expose: + - "85" + environment: + 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 + # 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 -with_alternative_group: - container_name: dh-env - environment: - - DHPARAM_BITS=3072 - - *default-host - image: *img-nginxproxy - volumes: *vols-common + with_alternative_group: + container_name: dh-env + environment: + - DHPARAM_BITS=3072 + - *default-host + image: *img-nginxproxy + volumes: *vols-common -with_invalid_group: - container_name: invalid-group-1024 - environment: - - DHPARAM_BITS=1024 - - *default-host - image: *img-nginxproxy - volumes: *vols-common + 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 - - ../../app/dhparam/ffdhe3072.pem:/etc/nginx/dhparam/dhparam.pem:ro + with_custom_file: + container_name: dh-file + image: *img-nginxproxy + environment: *env-common + volumes: + - *docker-sock + - *nginx-certs + - ../../app/dhparam/ffdhe3072.pem:/etc/nginx/dhparam/dhparam.pem:ro -with_skip: - container_name: dh-skip - environment: - - DHPARAM_SKIP=true - - *default-host - image: *img-nginxproxy - volumes: *vols-common + with_skip: + container_name: dh-skip + environment: + - DHPARAM_SKIP=true + - *default-host + image: *img-nginxproxy + volumes: *vols-common -with_skip_backward: - container_name: dh-skip-backward - environment: - - DHPARAM_GENERATION=false - - *default-host - image: *img-nginxproxy - volumes: *vols-common + with_skip_backward: + container_name: dh-skip-backward + environment: + - DHPARAM_GENERATION=false + - *default-host + image: *img-nginxproxy + volumes: *vols-common diff --git a/test/test_ssl/test_hsts.yml b/test/test_ssl/test_hsts.yml index da3b62962..b84fb8009 100644 --- a/test/test_ssl/test_hsts.yml +++ b/test/test_ssl/test_hsts.yml @@ -1,51 +1,54 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "web1.nginx-proxy.tld" +version: "2" -web2: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "web2.nginx-proxy.tld" - HSTS: "off" +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "web1.nginx-proxy.tld" -web3: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "web3.nginx-proxy.tld" - HSTS: "max-age=86400; includeSubDomains; preload" + web2: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "web2.nginx-proxy.tld" + HSTS: "off" -web4: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "web4.nginx-proxy.tld" - HSTS: "off" - HTTPS_METHOD: "noredirect" + web3: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "web3.nginx-proxy.tld" + HSTS: "max-age=86400; includeSubDomains; preload" -web5: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: http3-vhost-enabled.nginx-proxy.tld - labels: - com.github.nginx-proxy.nginx-proxy.http3.enable: "true" + web4: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "web4.nginx-proxy.tld" + HSTS: "off" + HTTPS_METHOD: "noredirect" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs:/etc/nginx/certs:ro + web5: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: http3-vhost-enabled.nginx-proxy.tld + labels: + com.github.nginx-proxy.nginx-proxy.http3.enable: "true" + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs:/etc/nginx/certs:ro diff --git a/test/test_ssl/test_https_port.yml b/test/test_ssl/test_https_port.yml index 7b674d76a..047054a39 100644 --- a/test/test_ssl/test_https_port.yml +++ b/test/test_ssl/test_https_port.yml @@ -1,16 +1,19 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "*.nginx-proxy.tld" +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs:/etc/nginx/certs:ro - environment: - HTTP_PORT: 8080 - HTTPS_PORT: 8443 \ No newline at end of file +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "*.nginx-proxy.tld" + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs:/etc/nginx/certs:ro + environment: + HTTP_PORT: 8080 + HTTPS_PORT: 8443 diff --git a/test/test_ssl/test_nohttp.yml b/test/test_ssl/test_nohttp.yml index 48a7aa3c6..40b393ad6 100644 --- a/test/test_ssl/test_nohttp.yml +++ b/test/test_ssl/test_nohttp.yml @@ -1,15 +1,17 @@ -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: "82" - VIRTUAL_HOST: "web2.nginx-proxy.tld" - HTTPS_METHOD: nohttp +version: "2" +services: + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "web2.nginx-proxy.tld" + HTTPS_METHOD: nohttp -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs:/etc/nginx/certs:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs:/etc/nginx/certs:ro diff --git a/test/test_ssl/test_nohttps.yml b/test/test_ssl/test_nohttps.yml index 3f3df1957..f2b07574b 100644 --- a/test/test_ssl/test_nohttps.yml +++ b/test/test_ssl/test_nohttps.yml @@ -1,14 +1,16 @@ -web: - image: web - expose: - - "83" - environment: - WEB_PORTS: "83" - VIRTUAL_HOST: "web.nginx-proxy.tld" - HTTPS_METHOD: nohttps +version: "2" +services: + web: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: "web.nginx-proxy.tld" + HTTPS_METHOD: nohttps -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_ssl/test_noredirect.yml b/test/test_ssl/test_noredirect.yml index ecd93f6a6..8ee845525 100644 --- a/test/test_ssl/test_noredirect.yml +++ b/test/test_ssl/test_noredirect.yml @@ -1,15 +1,17 @@ -web3: - image: web - expose: - - "83" - environment: - WEB_PORTS: "83" - VIRTUAL_HOST: "web3.nginx-proxy.tld" - HTTPS_METHOD: noredirect +version: "2" +services: + web3: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: "web3.nginx-proxy.tld" + HTTPS_METHOD: noredirect -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs:/etc/nginx/certs:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs:/etc/nginx/certs:ro diff --git a/test/test_ssl/test_virtual_path.yml b/test/test_ssl/test_virtual_path.yml index 22603217e..2494d35d8 100644 --- a/test/test_ssl/test_virtual_path.yml +++ b/test/test_ssl/test_virtual_path.yml @@ -1,26 +1,28 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "www.nginx-proxy.tld" - VIRTUAL_PATH: "/web1/" - VIRTUAL_DEST: "/" +version: "2" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: "82" - VIRTUAL_HOST: "www.nginx-proxy.tld" - VIRTUAL_PATH: "/web2/" - VIRTUAL_DEST: "/" +services: + 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 - - ./certs:/etc/nginx/certs:ro + 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 + - ./certs:/etc/nginx/certs:ro diff --git a/test/test_ssl/test_wildcard.yml b/test/test_ssl/test_wildcard.yml index e1504edeb..ea8c596cc 100644 --- a/test/test_ssl/test_wildcard.yml +++ b/test/test_ssl/test_wildcard.yml @@ -1,13 +1,16 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "*.nginx-proxy.tld" +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs:/etc/nginx/certs:ro +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "*.nginx-proxy.tld" + + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs:/etc/nginx/certs:ro diff --git a/test/test_trust-downstream-proxy/test_default.yml b/test/test_trust-downstream-proxy/test_default.yml index c420d806b..936dbad53 100644 --- a/test/test_trust-downstream-proxy/test_default.yml +++ b/test/test_trust-downstream-proxy/test_default.yml @@ -1,16 +1,18 @@ -web: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: web.nginx-proxy.tld - HTTPS_METHOD: noredirect +version: "2" +services: + web: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: web.nginx-proxy.tld + HTTPS_METHOD: noredirect -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro - - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro + - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro diff --git a/test/test_trust-downstream-proxy/test_disabled.yml b/test/test_trust-downstream-proxy/test_disabled.yml index 860e5f95e..9318d6381 100644 --- a/test/test_trust-downstream-proxy/test_disabled.yml +++ b/test/test_trust-downstream-proxy/test_disabled.yml @@ -1,18 +1,20 @@ -web: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: web.nginx-proxy.tld - HTTPS_METHOD: noredirect +version: "2" +services: + web: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: web.nginx-proxy.tld + HTTPS_METHOD: noredirect -sut: - image: nginxproxy/nginx-proxy:test - environment: - TRUST_DOWNSTREAM_PROXY: "false" - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro - - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro + sut: + image: nginxproxy/nginx-proxy:test + environment: + TRUST_DOWNSTREAM_PROXY: "false" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro + - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro diff --git a/test/test_trust-downstream-proxy/test_enabled.yml b/test/test_trust-downstream-proxy/test_enabled.yml index 7b2a8de95..9a3e97554 100644 --- a/test/test_trust-downstream-proxy/test_enabled.yml +++ b/test/test_trust-downstream-proxy/test_enabled.yml @@ -1,18 +1,20 @@ -web: - image: web - expose: - - "80" - environment: - WEB_PORTS: 80 - VIRTUAL_HOST: web.nginx-proxy.tld - HTTPS_METHOD: noredirect +version: "2" +services: + web: + image: web + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: web.nginx-proxy.tld + HTTPS_METHOD: noredirect -sut: - image: nginxproxy/nginx-proxy:test - environment: - TRUST_DOWNSTREAM_PROXY: "true" - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro - - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro + sut: + image: nginxproxy/nginx-proxy:test + environment: + TRUST_DOWNSTREAM_PROXY: "true" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro + - ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro diff --git a/test/test_upstream-name/test_predictable-name.yml b/test/test_upstream-name/test_predictable-name.yml index cd8d25080..b5caad0fb 100644 --- a/test/test_upstream-name/test_predictable-name.yml +++ b/test/test_upstream-name/test_predictable-name.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" services: web: diff --git a/test/test_upstream-name/test_sha1-name.yml b/test/test_upstream-name/test_sha1-name.yml index 54989ae44..b52a5c946 100644 --- a/test/test_upstream-name/test_sha1-name.yml +++ b/test/test_upstream-name/test_sha1-name.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" services: web: diff --git a/test/test_vhost-empty-string.yml b/test/test_vhost-empty-string.yml index 83dd55457..9d2ff529e 100644 --- a/test/test_vhost-empty-string.yml +++ b/test/test_vhost-empty-string.yml @@ -1,8 +1,11 @@ +version: "2" + services: sut: image: nginxproxy/nginx-proxy:test volumes: - /var/run/docker.sock:/tmp/docker.sock:ro + web1: image: web expose: @@ -11,6 +14,7 @@ services: WEB_PORTS: "81" # The space is intentional (should be trimmed). VIRTUAL_HOST: " " + web2: image: web expose: @@ -19,6 +23,7 @@ services: WEB_PORTS: "82" # The space is intentional (should be trimmed). VIRTUAL_HOST: "web2.nginx-proxy.test ," + web3: image: web expose: @@ -27,6 +32,7 @@ services: WEB_PORTS: "83" # The space is intentional (should be trimmed). VIRTUAL_HOST: " ,web3.nginx-proxy.test" + web4: image: web expose: diff --git a/test/test_vhost-in-multiple-networks.yml b/test/test_vhost-in-multiple-networks.yml index 280af0401..4e9bb3e9e 100644 --- a/test/test_vhost-in-multiple-networks.yml +++ b/test/test_vhost-in-multiple-networks.yml @@ -1,4 +1,4 @@ -version: '2' +version: "2" networks: net1: {} diff --git a/test/test_virtual-path/test_custom_conf.yml b/test/test_virtual-path/test_custom_conf.yml index 40ab51244..2c4d6b9e8 100644 --- a/test/test_virtual-path/test_custom_conf.yml +++ b/test/test_virtual-path/test_custom_conf.yml @@ -1,48 +1,49 @@ +version: "2" -foo: - image: web - expose: - - "42" - environment: - WEB_PORTS: "42" - VIRTUAL_HOST: "foo.nginx-proxy.test" +services: + 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/" - VIRTUAL_DEST: "/" + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: "82" - VIRTUAL_HOST: "nginx-proxy.test" - VIRTUAL_PATH: "/web2/" - VIRTUAL_DEST: "/" + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "nginx-proxy.test" + 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: - DEFAULT_ROOT: 418 - volumes: - - /var/run/docker.sock:/tmp/docker.sock: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 + 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: + DEFAULT_ROOT: 418 + volumes: + - /var/run/docker.sock:/tmp/docker.sock: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 ee87e8d61..9b15c7416 100644 --- a/test/test_virtual-path/test_forwarding.yml +++ b/test/test_virtual-path/test_forwarding.yml @@ -1,17 +1,20 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "www.nginx-proxy.tld" - VIRTUAL_PATH: "/web1/" - VIRTUAL_DEST: "/" +version: "2" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./certs:/etc/nginx/certs:ro - environment: - - DEFAULT_ROOT=301 http://$$host/web1$$request_uri +services: + 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 + - ./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 be3248c7f..a250a1d27 100644 --- a/test/test_virtual-path/test_location_precedence.yml +++ b/test/test_virtual-path/test_location_precedence.yml @@ -1,37 +1,40 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "foo.nginx-proxy.test" - VIRTUAL_PATH: "/web1/" - VIRTUAL_DEST: "/" +version: "2" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: "82" - VIRTUAL_HOST: "bar.nginx-proxy.test" - VIRTUAL_PATH: "/web2/" - VIRTUAL_DEST: "/" +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "foo.nginx-proxy.test" + VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" -web3: - image: web - expose: - - "83" - environment: - WEB_PORTS: "83" - VIRTUAL_HOST: "bar.nginx-proxy.test" - VIRTUAL_PATH: "/web3/" - VIRTUAL_DEST: "/" + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "bar.nginx-proxy.test" + VIRTUAL_PATH: "/web2/" + VIRTUAL_DEST: "/" -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock: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 + 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 + - ./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 9f6a54f51..ac70297ec 100644 --- a/test/test_virtual-path/test_virtual_paths.yml +++ b/test/test_virtual-path/test_virtual_paths.yml @@ -1,42 +1,44 @@ +version: "2" -foo: - image: web - expose: - - "42" - environment: - WEB_PORTS: "42" - VIRTUAL_HOST: "foo.nginx-proxy.test" +services: + 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/" - VIRTUAL_DEST: "/" + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/web1/" + VIRTUAL_DEST: "/" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: "82" - VIRTUAL_HOST: "nginx-proxy.test" - VIRTUAL_PATH: "/web2/" - VIRTUAL_DEST: "/" + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "nginx-proxy.test" + VIRTUAL_PATH: "/web2/" + VIRTUAL_DEST: "/" -web3: - image: web - expose: - - "83" - environment: - WEB_PORTS: "83" - VIRTUAL_HOST: "nginx-proxy.test" - VIRTUAL_PATH: "/" + 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 + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro diff --git a/test/test_wildcard_host.yml b/test/test_wildcard_host.yml index cd6687393..47e75e447 100644 --- a/test/test_wildcard_host.yml +++ b/test/test_wildcard_host.yml @@ -1,37 +1,39 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: "81" - VIRTUAL_HOST: "*.nginx-proxy.test" +version: "2" -web2: - image: web - expose: - - "82" - environment: - WEB_PORTS: "82" - VIRTUAL_HOST: "test.nginx-proxy.*" +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "*.nginx-proxy.test" -web3: - image: web - expose: - - "83" - environment: - WEB_PORTS: "83" - VIRTUAL_HOST: ~^web3\..*\.nginx-proxy\.regexp + web2: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: "test.nginx-proxy.*" -web4: - image: web - expose: - - "84" - environment: - WEB_PORTS: "84" - VIRTUAL_HOST: ~^web4\..*\.nginx-proxy\.regexp$$ # we need to double the `$` because of docker compose variable interpolation + web3: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: ~^web3\..*\.nginx-proxy\.regexp + web4: + image: web + expose: + - "84" + environment: + WEB_PORTS: "84" + VIRTUAL_HOST: ~^web4\..*\.nginx-proxy\.regexp$$ # we need to double the `$` because of docker compose variable interpolation -sut: - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro From c4cf0af3732e8f2d9ff5b58fe1e089571eaf7f06 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 11 Dec 2023 15:06:29 +0100 Subject: [PATCH 13/58] test: fix failing tests --- test/test_events.py | 2 ++ test/test_server-down/test_load-balancing.yml | 2 +- test/test_server-down/test_server-down.yml | 2 +- test/test_ssl/test_dhparam.py | 6 ++++-- test/test_virtual-path/test_virtual_paths.py | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/test/test_events.py b/test/test_events.py index b5da3dd4a..9b99e93b8 100644 --- a/test/test_events.py +++ b/test/test_events.py @@ -22,6 +22,7 @@ def web1(docker_compose): }, ports={"81/tcp": None} ) + docker_compose.networks.get("test_default").connect(container) sleep(2) # give it some time to initialize and for docker-gen to detect it yield container try: @@ -46,6 +47,7 @@ def web2(docker_compose): }, ports={"82/tcp": None} ) + docker_compose.networks.get("test_default").connect(container) sleep(2) # give it some time to initialize and for docker-gen to detect it yield container try: diff --git a/test/test_server-down/test_load-balancing.yml b/test/test_server-down/test_load-balancing.yml index bde23d613..232259020 100644 --- a/test/test_server-down/test_load-balancing.yml +++ b/test/test_server-down/test_load-balancing.yml @@ -24,7 +24,7 @@ services: environment: WEB_PORTS: 83 VIRTUAL_HOST: web.nginx-proxy.tld - net: "none" + network_mode: "none" sut: image: nginxproxy/nginx-proxy:test diff --git a/test/test_server-down/test_server-down.yml b/test/test_server-down/test_server-down.yml index d4d109a33..98fd30f28 100644 --- a/test/test_server-down/test_server-down.yml +++ b/test/test_server-down/test_server-down.yml @@ -8,7 +8,7 @@ services: environment: WEB_PORTS: 81 VIRTUAL_HOST: web.nginx-proxy.tld - net: "none" + network_mode: "none" sut: image: nginxproxy/nginx-proxy:test diff --git a/test/test_ssl/test_dhparam.py b/test/test_ssl/test_dhparam.py index d4d64a34c..65dcfae89 100644 --- a/test/test_ssl/test_dhparam.py +++ b/test/test_ssl/test_dhparam.py @@ -3,6 +3,7 @@ import backoff import docker +import pprint import pytest docker_client = docker.from_env() @@ -60,7 +61,8 @@ def versiontuple(v): @require_openssl("1.0.2") def negotiate_cipher(sut_container, additional_params='', grep='Cipher is'): - host = f"{sut_container.attrs['NetworkSettings']['IPAddress']}:443" + sut_container.reload() + host = f"{sut_container.attrs['NetworkSettings']['Networks']['test_ssl_default']['IPAddress']}:443" try: # Enforce TLS 1.2 as newer versions don't support custom dhparam or ciphersuite preference. @@ -77,7 +79,7 @@ def negotiate_cipher(sut_container, additional_params='', grep='Cipher is'): except subprocess.CalledProcessError as e: # Output a more helpful error, the original exception in this case isn't that helpful. # `from None` to ignore undesired output from exception chaining. - raise Exception("Failed to process CLI request:\n" + e.stderr) from None + raise Exception(f"Failed to process CLI request openssl s_client -connect {host} -tls1_2 {additional_params}:\n" + e.stderr) from None # The default `dh_bits` can vary due to configuration. diff --git a/test/test_virtual-path/test_virtual_paths.py b/test/test_virtual-path/test_virtual_paths.py index 115d47fee..a91a8dd42 100644 --- a/test/test_virtual-path/test_virtual_paths.py +++ b/test/test_virtual-path/test_virtual_paths.py @@ -39,6 +39,7 @@ def web4(docker_compose): }, ports={"84/tcp": None} ) + docker_compose.networks.get("test_virtual-path_default").connect(container) sleep(2) # give it some time to initialize and for docker-gen to detect it yield container try: From c1617a6face74d58a835c1fc9424c2e249382064 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 21:07:53 +0000 Subject: [PATCH 14/58] ci: bump docker from 6.1.3 to 7.0.0 in /test/requirements Bumps [docker](https://github.com/docker/docker-py) from 6.1.3 to 7.0.0. - [Release notes](https://github.com/docker/docker-py/releases) - [Commits](https://github.com/docker/docker-py/compare/6.1.3...7.0.0) --- updated-dependencies: - dependency-name: docker 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 079a74e64..985fc9597 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -1,4 +1,4 @@ backoff==2.2.1 -docker==6.1.3 +docker==7.0.0 pytest==7.4.3 requests==2.31.0 From 7d44f98e4fdaff0c80240ee60f86629f990fd95b Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 12 Dec 2023 22:16:32 +0100 Subject: [PATCH 15/58] test: remove unused import --- test/test_ssl/test_dhparam.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_ssl/test_dhparam.py b/test/test_ssl/test_dhparam.py index 65dcfae89..1cbc0ac9a 100644 --- a/test/test_ssl/test_dhparam.py +++ b/test/test_ssl/test_dhparam.py @@ -3,7 +3,6 @@ import backoff import docker -import pprint import pytest docker_client = docker.from_env() From 005488886d6d19168a21329665ed237778ae1fc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:40:22 +0000 Subject: [PATCH 16/58] build: bump nginxproxy/docker-gen from 0.10.7 to 0.11.0 Bumps nginxproxy/docker-gen from 0.10.7 to 0.11.0. --- updated-dependencies: - dependency-name: nginxproxy/docker-gen 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 5c44047af..137b15660 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM nginxproxy/docker-gen:0.10.7-debian AS docker-gen +FROM nginxproxy/docker-gen:0.11.0-debian AS docker-gen FROM nginxproxy/forego:0.17.2-debian AS forego diff --git a/Dockerfile.alpine b/Dockerfile.alpine index ce2f7a615..a00a0b5a1 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,4 +1,4 @@ -FROM nginxproxy/docker-gen:0.10.7 AS docker-gen +FROM nginxproxy/docker-gen:0.11.0 AS docker-gen FROM nginxproxy/forego:0.17.2 AS forego From db55ddcab4cc6920f1e5a997a2735c44de665fbf Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 15 May 2023 22:22:05 +0200 Subject: [PATCH 17/58] ci: use build matrix rather than separate jobs --- .github/workflows/build-publish.yml | 106 ++++++---------------------- Dockerfile => Dockerfile.debian | 0 Makefile | 2 +- 3 files changed, 23 insertions(+), 85 deletions(-) rename Dockerfile => Dockerfile.debian (100%) diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 9bd3eaf87..be406f66b 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -19,8 +19,11 @@ on: - "*.md" jobs: - multiarch-build-debian: - name: Build and publish Debian image + multiarch-build: + name: Build and publish image + strategy: + matrix: + base: [alpine, debian] runs-on: ubuntu-latest steps: - name: Checkout @@ -32,77 +35,12 @@ jobs: id: nginx-proxy_version run: echo "VERSION=$(git describe --tags)" >> "$GITHUB_OUTPUT" - - name: Get Docker tags for Debian based image - id: docker_meta_debian - uses: docker/metadata-action@v5 - with: - images: | - ghcr.io/nginx-proxy/nginx-proxy - nginxproxy/nginx-proxy - jwilder/nginx-proxy - tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=raw,value=latest,enable={{is_default_branch}} - labels: | - org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder - org.opencontainers.image.version=${{ steps.nginx-proxy_version.outputs.VERSION }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Retrieve docker-gen version id: docker-gen_version - run: sed -n -e 's;^FROM nginxproxy/docker-gen:\([0-9.]*\).*;VERSION=\1;p' Dockerfile >> "$GITHUB_OUTPUT" - - - name: Build and push the Debian based image - id: docker_build_debian - uses: docker/build-push-action@v5 - with: - context: . - file: Dockerfile - build-args: | - NGINX_PROXY_VERSION=${{ steps.nginx-proxy_version.outputs.VERSION }} - DOCKER_GEN_VERSION=${{ steps.docker-gen_version.outputs.VERSION }} - platforms: linux/amd64,linux/arm64,linux/arm/v7 - push: true - tags: ${{ steps.docker_meta_debian.outputs.tags }} - labels: ${{ steps.docker_meta_debian.outputs.labels }} + run: sed -n -e 's;^FROM nginxproxy/docker-gen:\([0-9.]*\).*;VERSION=\1;p' Dockerfile.${{ matrix.base }} >> "$GITHUB_OUTPUT" - - name: Images digests - run: echo ${{ steps.docker_build_debian.outputs.digest }} - - multiarch-build-alpine: - name: Build and publish Alpine image - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Retrieve nginx-proxy version - id: nginx-proxy_version - run: echo "VERSION=$(git describe --tags)" >> "$GITHUB_OUTPUT" - - - name: Get Docker tags for Alpine based image - id: docker_meta_alpine + - name: Get Docker tags + id: docker_meta uses: docker/metadata-action@v5 with: images: | @@ -110,13 +48,17 @@ jobs: nginxproxy/nginx-proxy jwilder/nginx-proxy tags: | - type=semver,suffix=-alpine,pattern={{version}} - type=semver,suffix=-alpine,pattern={{major}}.{{minor}} - type=raw,value=alpine,enable={{is_default_branch}} + type=semver,pattern={{version}},enable=${{ matrix.base == 'debian' }} + type=semver,pattern={{major}}.{{minor}},enable=${{ matrix.base == 'debian' }} + type=semver,suffix=-alpine,pattern={{version}},enable=${{ matrix.base == 'alpine' }} + type=semver,suffix=-alpine,pattern={{major}}.{{minor}},enable=${{ matrix.base == 'alpine' }} + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' && matrix.base == 'debian' }} + type=raw,value=alpine,enable=${{ github.ref == 'refs/heads/main' && matrix.base == 'alpine' }} labels: | org.opencontainers.image.authors=Nicolas Duchon (@buchdag), Jason Wilder org.opencontainers.image.version=${{ steps.nginx-proxy_version.outputs.VERSION }} - flavor: latest=false + flavor: | + latest=false - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -137,23 +79,19 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Retrieve docker-gen version - id: docker-gen_version - run: sed -n -e 's;^FROM nginxproxy/docker-gen:\([0-9.]*\).*;VERSION=\1;p' Dockerfile >> "$GITHUB_OUTPUT" - - - name: Build and push the Alpine based image - id: docker_build_alpine + - name: Build and push the image + id: docker_build uses: docker/build-push-action@v5 with: context: . - file: Dockerfile.alpine + file: Dockerfile.${{ matrix.base }} build-args: | NGINX_PROXY_VERSION=${{ steps.nginx-proxy_version.outputs.VERSION }} DOCKER_GEN_VERSION=${{ steps.docker-gen_version.outputs.VERSION }} platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true - tags: ${{ steps.docker_meta_alpine.outputs.tags }} - labels: ${{ steps.docker_meta_alpine.outputs.labels }} + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} - name: Images digests - run: echo ${{ steps.docker_build_alpine.outputs.digest }} + run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/Dockerfile b/Dockerfile.debian similarity index 100% rename from Dockerfile rename to Dockerfile.debian diff --git a/Makefile b/Makefile index 5e53e3636..e735e6aa1 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ build-webserver: docker build --pull -t web test/requirements/web build-nginx-proxy-test-debian: - docker build --pull --build-arg NGINX_PROXY_VERSION="test" -t nginxproxy/nginx-proxy:test . + docker build --pull --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.debian -t nginxproxy/nginx-proxy:test . build-nginx-proxy-test-alpine: docker build --pull --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test . From e2997d9fb9a22bc98d361a35ea6c6029b1d68033 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 15 May 2023 22:23:58 +0200 Subject: [PATCH 18/58] ci: enable gha caching on docker/build-push-action --- .github/workflows/build-publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index be406f66b..5c823c979 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -92,6 +92,8 @@ jobs: push: true tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max - name: Images digests run: echo ${{ steps.docker_build.outputs.digest }} From a2ade38abb111aece48a5c120650a4cdf2a607ac Mon Sep 17 00:00:00 2001 From: Gilles Filippini Date: Tue, 19 Dec 2023 19:20:56 +0100 Subject: [PATCH 19/58] fix #2310 Check the '.Internal' network property, because the .Gateway property is defined for internal networks as well. --- nginx.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index f830fd2ee..66324ff8d 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -75,7 +75,7 @@ {{- continue }} {{- end }} {{- range sortObjectsByKeysAsc $.globals.CurrentContainer.Networks "Name" }} - {{- if and . .Gateway }} + {{- if and . .Gateway (not .Internal) }} # container is in host network mode, using {{ .Name }} gateway IP {{- $ip = .Gateway }} {{- break }} From 5d37cab19b9fd94d97902700dc1a2819e9193474 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 19 Dec 2023 19:26:13 +0100 Subject: [PATCH 20/58] ci: add explicit provenance and enable sbom --- .github/workflows/build-publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 5c823c979..1d4739323 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -89,7 +89,9 @@ jobs: NGINX_PROXY_VERSION=${{ steps.nginx-proxy_version.outputs.VERSION }} DOCKER_GEN_VERSION=${{ steps.docker-gen_version.outputs.VERSION }} platforms: linux/amd64,linux/arm64,linux/arm/v7 + sbom: true push: true + provenance: mode=max tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} cache-from: type=gha From 2c3883ca8108a8be9f0453d41fae990f4a75b801 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:07:02 +0000 Subject: [PATCH 21/58] build: bump nginxproxy/forego from 0.17.2-debian to 0.17.3-debian Bumps nginxproxy/forego from 0.17.2-debian to 0.17.3-debian. --- updated-dependencies: - dependency-name: nginxproxy/forego dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile.alpine | 2 +- Dockerfile.debian | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index a00a0b5a1..2fb2cdaef 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,6 +1,6 @@ FROM nginxproxy/docker-gen:0.11.0 AS docker-gen -FROM nginxproxy/forego:0.17.2 AS forego +FROM nginxproxy/forego:0.17.3 AS forego # Build the final image FROM nginx:1.25.3-alpine diff --git a/Dockerfile.debian b/Dockerfile.debian index 137b15660..2b7801ccc 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -1,6 +1,6 @@ FROM nginxproxy/docker-gen:0.11.0-debian AS docker-gen -FROM nginxproxy/forego:0.17.2-debian AS forego +FROM nginxproxy/forego:0.17.3-debian AS forego # Build the final image FROM nginx:1.25.3 From 980470377a957dee31ff2e533babb42f8c79d495 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 19 Dec 2023 20:27:13 +0100 Subject: [PATCH 22/58] ci: Docker Hub description update --- .github/workflows/dockerhub-description.yml | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/dockerhub-description.yml diff --git a/.github/workflows/dockerhub-description.yml b/.github/workflows/dockerhub-description.yml new file mode 100644 index 000000000..594e132b1 --- /dev/null +++ b/.github/workflows/dockerhub-description.yml @@ -0,0 +1,27 @@ +name: Update Docker Hub Description + +on: + push: + branches: + - main + paths: + - README.md + - .github/workflows/dockerhub-description.yml + +jobs: + dockerHubDescription: + name: Update Docker Hub Description + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Docker Hub Description + uses: peter-evans/dockerhub-description@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN_RWD }} + repository: nginxproxy/nginx-proxy + short-description: ${{ github.event.repository.description }} + enable-url-completion: true From 5d2f51dfe27de9f01c45f96f0b3995941ce919a6 Mon Sep 17 00:00:00 2001 From: Gilles Filippini Date: Tue, 12 Dec 2023 19:24:14 +0100 Subject: [PATCH 23/58] Fix test case assertion depending on python version --- .../wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py b/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py index 590eafc2f..445377912 100644 --- a/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py +++ b/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py @@ -27,7 +27,8 @@ def test_https_get_served(docker_compose, nginxproxy, subdomain): def test_https_request_to_nohttps_vhost_goes_to_fallback_server(docker_compose, nginxproxy): with pytest.raises( (CertificateError, SSLError) ) as excinfo: nginxproxy.get("https://3.web.nginx-proxy.tld/port") - assert """certificate is not valid for '3.web.nginx-proxy.tld'""" in str(excinfo.value) + assert """certificate is not valid for '3.web.nginx-proxy.tld'""" in str(excinfo.value) or \ + """hostname '3.web.nginx-proxy.tld' doesn't match 'nginx-proxy.tld'""" in str(excinfo.value) r = nginxproxy.get("https://3.web.nginx-proxy.tld/port", verify=False) assert r.status_code == 503 From 9e77e81e7dbd99e1de0d4978233be2e1695a8bf5 Mon Sep 17 00:00:00 2001 From: Gilles Filippini Date: Tue, 19 Dec 2023 21:07:30 +0100 Subject: [PATCH 24/58] Tests: support custom 'docker compose' command Enable overriding default 'docker compose' command with environment variable 'DOCKER_COMPOSE'. This way docker compose v1 is still supported with: $ DOCKER_COMPOSE=docker-compose pytest This is important because people using the Debian packaged docker compose are stuck to v1. --- test/README.md | 3 +++ test/conftest.py | 13 +++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/README.md b/test/README.md index 5a93e1bb1..056cd375b 100644 --- a/test/README.md +++ b/test/README.md @@ -28,6 +28,9 @@ need more verbosity ? pytest -s +Note: By default this test suite relies on Docker Compose v2 with the command `docker compose`. It still supports Docker Compose v1 via the `DOCKER_COMPOSE` environment variable: + + DOCKER_COMPOSE=docker-compose pytest Run one single test module -------------------------- diff --git a/test/conftest.py b/test/conftest.py index 938be6bcd..7fa269a61 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -26,6 +26,7 @@ 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 +DOCKER_COMPOSE = os.environ.get('DOCKER_COMPOSE', 'docker compose') docker_client = docker.from_env() @@ -301,19 +302,19 @@ def get_nginx_conf_from_container(container): def docker_compose_up(compose_file='docker-compose.yml'): - logging.info(f'docker compose -f {compose_file} up -d') + logging.info(f'{DOCKER_COMPOSE} -f {compose_file} up -d') try: - subprocess.check_output(shlex.split(f'docker compose -f {compose_file} up -d'), stderr=subprocess.STDOUT) + subprocess.check_output(shlex.split(f'{DOCKER_COMPOSE} -f {compose_file} up -d'), stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - pytest.fail(f"Error while runninng 'docker compose -f {compose_file} up -d':\n{e.output}", pytrace=False) + pytest.fail(f"Error while runninng '{DOCKER_COMPOSE} -f {compose_file} up -d':\n{e.output}", pytrace=False) def docker_compose_down(compose_file='docker-compose.yml'): - logging.info(f'docker compose -f {compose_file} down -v') + logging.info(f'{DOCKER_COMPOSE} -f {compose_file} down -v') try: - subprocess.check_output(shlex.split(f'docker compose -f {compose_file} down -v'), stderr=subprocess.STDOUT) + subprocess.check_output(shlex.split(f'{DOCKER_COMPOSE} -f {compose_file} down -v'), stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - pytest.fail(f"Error while runninng 'docker compose -f {compose_file} down -v':\n{e.output}", pytrace=False) + pytest.fail(f"Error while runninng '{DOCKER_COMPOSE} -f {compose_file} down -v':\n{e.output}", pytrace=False) def wait_for_nginxproxy_to_be_ready(): From c338a7cf22f3038c3d87255509f0ff1b1a23b8b9 Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:37:20 +0100 Subject: [PATCH 25/58] Color terminal output --- test/pytest.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/pytest.ini b/test/pytest.ini index 9ca76672c..10ef47813 100644 --- a/test/pytest.ini +++ b/test/pytest.ini @@ -1,5 +1,5 @@ [pytest] # disable the creation of the `.cache` folders -addopts = -p no:cacheprovider --ignore=requirements --ignore=certs -r s -v +addopts = -p no:cacheprovider --ignore=requirements --ignore=certs --color=yes -v markers = - incremental: mark a test as incremental. \ No newline at end of file + incremental: mark a test as incremental. From 51744959634af2b0bec2a3080b1762d72a82e9c5 Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:19:42 +0100 Subject: [PATCH 26/58] Fix test --- .../test_restart_while_missing_cert.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py b/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py index d7e4cbbb5..e984685db 100644 --- a/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py +++ b/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py @@ -9,8 +9,6 @@ script_dir = os.path.dirname(__file__) -pytestmark = pytest.mark.xfail() # TODO delete this marker once those issues are fixed - @pytest.fixture(scope="module", autouse=True) def certs(): """ @@ -45,7 +43,6 @@ def test_https_web_is_200(docker_compose, nginxproxy): assert "answer from port 81\n" in r.text -@pytest.mark.incremental def test_delete_cert_and_restart_reverseproxy(docker_compose): os.remove(join(script_dir, "tmp_certs", "web.nginx-proxy.crt")) docker_compose.containers.get("reverseproxy").restart() @@ -53,20 +50,17 @@ def test_delete_cert_and_restart_reverseproxy(docker_compose): assert "running" == docker_compose.containers.get("reverseproxy").status -@pytest.mark.incremental -def test_unknown_virtual_host_is_still_503(nginxproxy): +def test_unknown_virtual_host_is_still_503(docker_compose, nginxproxy): r = nginxproxy.get("http://foo.nginx-proxy/") assert r.status_code == 503 -@pytest.mark.incremental -def test_http_web_is_now_200(nginxproxy): +def test_http_web_is_now_200(docker_compose, nginxproxy): r = nginxproxy.get("http://web.nginx-proxy/port", allow_redirects=False) assert r.status_code == 200 assert "answer from port 81\n" == r.text -@pytest.mark.incremental def test_https_web_is_now_broken_since_there_is_no_cert(nginxproxy): with pytest.raises(ConnectionError): nginxproxy.get("https://web.nginx-proxy/port") From 33ceec07d82e2671d4bee144931b1811323497c0 Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:50:09 +0100 Subject: [PATCH 27/58] Sleep longer --- .../test_deleted_cert/test_restart_while_missing_cert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py b/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py index e984685db..7fdfa95f0 100644 --- a/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py +++ b/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py @@ -46,7 +46,7 @@ def test_https_web_is_200(docker_compose, nginxproxy): def test_delete_cert_and_restart_reverseproxy(docker_compose): os.remove(join(script_dir, "tmp_certs", "web.nginx-proxy.crt")) docker_compose.containers.get("reverseproxy").restart() - sleep(3) # give time for the container to initialize + sleep(5) # give time for the container to initialize assert "running" == docker_compose.containers.get("reverseproxy").status From a4ced5b8bdc8f9bebc0a3effd7286a60b0a92576 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sun, 24 Dec 2023 00:15:39 +0100 Subject: [PATCH 28/58] test: revert "Fix test" and "Sleep longer" This reverts commit 51744959634af2b0bec2a3080b1762d72a82e9c5. This reverts commit 33ceec07d82e2671d4bee144931b1811323497c0. --- .../test_restart_while_missing_cert.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py b/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py index 7fdfa95f0..d7e4cbbb5 100644 --- a/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py +++ b/test/stress_tests/test_deleted_cert/test_restart_while_missing_cert.py @@ -9,6 +9,8 @@ script_dir = os.path.dirname(__file__) +pytestmark = pytest.mark.xfail() # TODO delete this marker once those issues are fixed + @pytest.fixture(scope="module", autouse=True) def certs(): """ @@ -43,24 +45,28 @@ def test_https_web_is_200(docker_compose, nginxproxy): assert "answer from port 81\n" in r.text +@pytest.mark.incremental def test_delete_cert_and_restart_reverseproxy(docker_compose): os.remove(join(script_dir, "tmp_certs", "web.nginx-proxy.crt")) docker_compose.containers.get("reverseproxy").restart() - sleep(5) # give time for the container to initialize + sleep(3) # give time for the container to initialize assert "running" == docker_compose.containers.get("reverseproxy").status -def test_unknown_virtual_host_is_still_503(docker_compose, nginxproxy): +@pytest.mark.incremental +def test_unknown_virtual_host_is_still_503(nginxproxy): r = nginxproxy.get("http://foo.nginx-proxy/") assert r.status_code == 503 -def test_http_web_is_now_200(docker_compose, nginxproxy): +@pytest.mark.incremental +def test_http_web_is_now_200(nginxproxy): r = nginxproxy.get("http://web.nginx-proxy/port", allow_redirects=False) assert r.status_code == 200 assert "answer from port 81\n" == r.text +@pytest.mark.incremental def test_https_web_is_now_broken_since_there_is_no_cert(nginxproxy): with pytest.raises(ConnectionError): nginxproxy.get("https://web.nginx-proxy/port") From 7f43f0a66b75b184634d96efcd96e79f2d51cc7d Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sun, 24 Dec 2023 16:14:52 +0100 Subject: [PATCH 29/58] docs: split documentation --- README.md | 762 ++----------------------------------------------- docs/README.md | 728 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 754 insertions(+), 736 deletions(-) create mode 100644 docs/README.md diff --git a/README.md b/README.md index 6ff07f0bf..48d513f07 100644 --- a/README.md +++ b/README.md @@ -15,766 +15,56 @@ See [Automated Nginx Reverse Proxy for Docker](http://jasonwilder.com/blog/2014/ To run it: ```console -docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +docker run --detach \ + --name nginx-proxy \ + --publish 80:80 \ + --volume /var/run/docker.sock:/tmp/docker.sock:ro \ + nginxproxy/nginx-proxy:1.4 ``` -Then start any containers you want proxied with an env var `VIRTUAL_HOST=subdomain.youdomain.com` +Then start any containers (here an nginx container) you want proxied with an env var `VIRTUAL_HOST=subdomain.yourdomain.com` ```console -docker run -e VIRTUAL_HOST=foo.bar.com ... +docker run --detach \ + --name your-proxied-app \ + --env VIRTUAL_HOST=foo.bar.com \ + nginx ``` -The containers being proxied must [expose](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) the port to be proxied, either by using the `EXPOSE` directive in their `Dockerfile` or by using the `--expose` flag to `docker run` or `docker create` and be in the same network. 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. +Provided your DNS is setup to resolve `foo.bar.com` to the host running nginx-proxy, a request to `http://foo.bar.com` will then be routed to a container with the `VIRTUAL_HOST` env var set to `foo.bar.com` (in this case, the **your-proxied-app** container). -Provided your DNS is setup to forward foo.bar.com to the host running nginx-proxy, the request will be routed to a container with the `VIRTUAL_HOST` env var set. +The containers being proxied must : +- [expose](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) the port to be proxied, either by using the `EXPOSE` directive in their `Dockerfile` or by using the `--expose` flag to `docker run` or `docker create`. +- share at least one Docker network with the nginx-proxy container: 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. -Note: providing a port number in `VIRTUAL_HOST` isn't suported, please see [virtual ports](https://github.com/nginx-proxy/nginx-proxy#virtual-ports) or [custom external HTTP/HTTPS ports](https://github.com/nginx-proxy/nginx-proxy#custom-external-httphttps-ports) depending on what you want to achieve. +Note: providing a port number in `VIRTUAL_HOST` isn't suported, please see [virtual ports](https://github.com/nginx-proxy/nginx-proxy/docs#virtual-ports) or [custom external HTTP/HTTPS ports](https://github.com/nginx-proxy/nginx-proxy/docs#custom-external-httphttps-ports) depending on what you want to achieve. ### Image variants The nginx-proxy images are available in two flavors. -#### nginxproxy/nginx-proxy:latest +#### Debian based version -This image uses the debian:buster based nginx image. +This image is based on the nginx:mainline image, itself based on the debian slim image. ```console -docker pull nginxproxy/nginx-proxy:latest +docker pull nginxproxy/nginx-proxy:1.4 ``` -#### nginxproxy/nginx-proxy:alpine +#### Alpine based version (`-alpine` suffix) -This image is based on the nginx:alpine image. Use this image to fully support HTTP/2 (including ALPN required by recent Chrome versions). A valid certificate is required as well (see eg. below "SSL Support using an ACME CA" for more info). +This image is based on the nginx:alpine image. ```console -docker pull nginxproxy/nginx-proxy:alpine +docker pull nginxproxy/nginx-proxy:1.4-alpine ``` -### Docker Compose +#### :warning: a note on `latest` and `alpine`: -```yaml -version: '2' +It is not recommended to use the `latest` (`nginxproxy/nginx-proxy`, `nginxproxy/nginx-proxy:latest`) or `alpine` (`nginxproxy/nginx-proxy:alpine`) tag for production setups. -services: - nginx-proxy: - image: nginxproxy/nginx-proxy - ports: - - "80:80" - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro +Those tags points to the latest commit in the `main` branch. They do not carry any promise of stability, and using them will probably put your nginx-proxy setup at risk of experiencing uncontrolled updates to non backward compatible versions (or versions with breaking changes). You should always specify the version you want to use explicitly to ensure your setup doesn't break when the image is updated. - whoami: - image: jwilder/whoami - expose: - - "8000" - environment: - - VIRTUAL_HOST=whoami.example - - VIRTUAL_PORT=8000 -``` - -```console -docker compose up -curl -H "Host: whoami.example" localhost -``` - -Example output: -```console -I'm 5b129ab83266 -``` - -### IPv6 support - -You can activate the IPv6 support for the nginx-proxy container by passing the value `true` to the `ENABLE_IPV6` environment variable: - -```console -docker run -d -p 80:80 -e ENABLE_IPV6=true -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy -``` - -#### Scoped IPv6 Resolvers - -NginX does not support scoped IPv6 resolvers. In [docker-entrypoint.sh](./docker-entrypoint.sh) the resolvers are parsed from resolv.conf, but any scoped IPv6 addreses will be removed. - -#### IPv6 NAT - -By default, docker uses IPv6-to-IPv4 NAT. This means all client connections from IPv6 addresses will show docker's internal IPv4 host address. To see true IPv6 client IP addresses, you must [enable IPv6](https://docs.docker.com/config/daemon/ipv6/) and use [ipv6nat](https://github.com/robbertkl/docker-ipv6nat). You must also disable the userland proxy by adding `"userland-proxy": false` to `/etc/docker/daemon.json` and restarting the daemon. - -### Multiple Hosts - -If you need to support multiple virtual hosts for a container, you can separate each entry with commas. For example, `foo.bar.com,baz.bar.com,bar.com` and each host will be setup the same. - -### Virtual Ports - -When your container exposes only one port, nginx-proxy will default to this port, else to port 80. - -If you need to specify a different port, you can set a `VIRTUAL_PORT` env var to select a different one. This variable cannot be set to more than one port. - -For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrieved by order of precedence: -1. From the `VIRTUAL_PORT` environment variable -1. From the container's exposed port if there is only one -1. From the default port 80 when none of the above methods apply - -### 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\..*\.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, 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-Original-URI` 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 having 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`. - -#### 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. - -Exception: If this is set to the string `none`, no default `location /` directive will be generated. This makes it possible for you to provide your own `location /` directive in your [`/etc/nginx/vhost.d/VIRTUAL_HOST`](#per-virtual_host) or [`/etc/nginx/vhost.d/default`](#per-virtual_host-default-configuration) files. - -If unspecified, `DEFAULT_ROOT` defaults to `404`. - -Examples (YAML syntax): - - * `DEFAULT_ROOT: "none"` prevents `nginx-proxy` from generating a default `location /` directive. - * `DEFAULT_ROOT: "418"` returns a 418 error page instead of the normal 404 one. - * `DEFAULT_ROOT: "301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` redirects the client 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. For example, 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 - -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`. - -If you want your `nginx-proxy` container to be attached to a different network, you must pass the `--net=my-network` option in your `docker create` or `docker run` command. At the time of this writing, only a single network can be specified at container creation time. To attach to other networks, you can use the `docker network connect` command after your container is created: - -```console -docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro \ - --name my-nginx-proxy --net my-network nginxproxy/nginx-proxy -docker network connect my-other-network my-nginx-proxy -``` - -In this example, the `my-nginx-proxy` container will be connected to `my-network` and `my-other-network` and will be able to proxy to other containers attached to those networks. - -### Host networking - -`nginx-proxy` is compatible with containers using Docker's [host networking](https://docs.docker.com/network/host/), both with the proxy connected to one or more [bridge network](https://docs.docker.com/network/bridge/) (default or user created) or running in host network mode itself. - -Proxyed containers running in host network mode **must** use the [`VIRTUAL_PORT`](#virtual-ports) environment variable, as this is the only way for `nginx-proxy` to get the correct port (or a port at all) for those containers. - -### Custom external HTTP/HTTPS ports - -If you want to use `nginx-proxy` with different external ports that the default ones of `80` for `HTTP` traffic and `443` for `HTTPS` traffic, you'll have to use the environment variable(s) `HTTP_PORT` and/or `HTTPS_PORT` in addition to the changes to the Docker port mapping. If you change the `HTTPS` port, the redirect for `HTTPS` traffic will also be configured to redirect to the custom port. Typical usage, here with the custom ports `1080` and `10443`: - -```console -docker run -d -p 1080:1080 -p 10443:10443 -e HTTP_PORT=1080 -e HTTPS_PORT=10443 -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy -``` - -### Internet vs. Local Network Access - -If you allow traffic from the public internet to access your `nginx-proxy` container, you may want to restrict some containers to the internal network only, so they cannot be accessed from the public internet. On containers that should be restricted to the internal network, you should set the environment variable `NETWORK_ACCESS=internal`. By default, the *internal* network is defined as `127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16`. To change the list of networks considered internal, mount a file on the `nginx-proxy` at `/etc/nginx/network_internal.conf` with these contents, edited to suit your needs: - -```Nginx -# These networks are considered "internal" -allow 127.0.0.0/8; -allow 10.0.0.0/8; -allow 192.168.0.0/16; -allow 172.16.0.0/12; - -# Traffic from all other networks will be rejected -deny all; -``` - -When internal-only access is enabled, external clients will be denied with an `HTTP 403 Forbidden` - -> If there is a load-balancer / reverse proxy in front of `nginx-proxy` that hides the client IP (example: AWS Application/Elastic Load Balancer), you will need to use the nginx `realip` module (already installed) to extract the client's IP from the HTTP request headers. Please see the [nginx realip module configuration](http://nginx.org/en/docs/http/ngx_http_realip_module.html) for more details. This configuration can be added to a new config file and mounted in `/etc/nginx/conf.d/`. - -### SSL Backends - -If you would like the reverse proxy to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container. - -> Note: If you use `VIRTUAL_PROTO=https` and your backend container exposes port 80 and 443, `nginx-proxy` will use HTTPS on port 80. This is almost certainly not what you want, so you should also include `VIRTUAL_PORT=443`. - -### uWSGI Backends - -If you would like to connect to uWSGI backend, set `VIRTUAL_PROTO=uwsgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port. - -### FastCGI Backends - -If you would like to connect to FastCGI backend, set `VIRTUAL_PROTO=fastcgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port. - -### FastCGI File Root Directory - -If you use fastcgi,you can set `VIRTUAL_ROOT=xxx` for your root directory - -### Custom log format - -If you want to use a custom log format, you can set `LOG_FORMAT=xxx` on the proxy container. - -With docker compose take care to escape the `$` character with `$$` to avoid variable interpolation. Example: `$remote_addr` becomes `$$remote_addr`. - -### Default Host - -To set the default host for nginx use the env var `DEFAULT_HOST=foo.bar.com` for example - -```console -docker run -d -p 80:80 -e DEFAULT_HOST=foo.bar.com -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy -``` - -nginx-proxy will then redirect all requests to a container where `VIRTUAL_HOST` is set to `DEFAULT_HOST`, if they don't match any (other) `VIRTUAL_HOST`. Using the example above requests without matching `VIRTUAL_HOST` will be redirected to a plain nginx instance after running the following command: - -```console -docker run -d -e VIRTUAL_HOST=foo.bar.com nginx -``` - -### Separate Containers - -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. - -You can demo this pattern with docker compose: - -```console -docker compose --file docker-compose-separate-containers.yml up -curl -H "Host: whoami.example" localhost -``` - -Example output: -```console -I'm 5b129ab83266 -``` - -To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/nginx-proxy/nginx-proxy/blob/main/nginx.tmpl) on your host system. - -First start nginx with a volume: - - -```console -docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx -``` - -Then start the docker-gen container with the shared volume and template: - -```console -docker run --volumes-from nginx \ - -v /var/run/docker.sock:/tmp/docker.sock:ro \ - -v $(pwd):/etc/docker-gen/templates \ - -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. - -```console -docker run -e VIRTUAL_HOST=foo.bar.com ... -``` - -### SSL Support using an ACME CA - -[acme-companion](https://github.com/nginx-proxy/acme-companion) is a lightweight companion container for the nginx-proxy. It allows the automated creation/renewal of SSL certificates using the ACME protocol. - -### SSL Support - -SSL is supported using single host, wildcard and SNI certificates using naming conventions for certificates or optionally specifying a cert name (for SNI) as an environment variable. - -To enable SSL: - -```console -docker run -d -p 80:80 -p 443:443 -v /path/to/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy -``` - -The contents of `/path/to/certs` should contain the certificates and private keys for any virtual hosts in use. The certificate and keys should be named after the virtual host with a `.crt` and `.key` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a `foo.bar.com.crt` and `foo.bar.com.key` file in the certs directory. - -If you are running the container in a virtualized environment (Hyper-V, VirtualBox, etc...), /path/to/certs must exist in that environment or be made accessible to that environment. By default, Docker is not able to mount directories on the host machine to containers running in a virtual machine. - -#### Diffie-Hellman Groups - -[RFC7919 groups](https://datatracker.ietf.org/doc/html/rfc7919#appendix-A) with key lengths of 2048, 3072, and 4096 bits are [provided by `nginx-proxy`](https://github.com/nginx-proxy/nginx-proxy/dhparam). The ENV `DHPARAM_BITS` can be set to `2048` or `3072` to change from the default 4096-bit key. The DH key file will be located in the container at `/etc/nginx/dhparam/dhparam.pem`. Mounting a different `dhparam.pem` file at that location will override the RFC7919 key. - -To use custom `dhparam.pem` files per-virtual-host, the files should be named after the virtual host with a `dhparam` suffix and `.pem` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a `foo.bar.com.dhparam.pem` file in the `/etc/nginx/certs` directory. - -> 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 [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`. - -```console -docker run -e DHPARAM_SKIP=true .... -``` - -#### Wildcard Certificates - -Wildcard certificates and keys should be named after the domain name with a `.crt` and `.key` extension. For example `VIRTUAL_HOST=foo.bar.com` would use cert name `bar.com.crt` and `bar.com.key`. - -#### SNI - -If your certificate(s) supports multiple domain names, you can start a container with `CERT_NAME=` to identify the certificate to be used. For example, a certificate for `*.foo.com` and `*.bar.com` could be named `shared.crt` and `shared.key`. A container running with `VIRTUAL_HOST=foo.bar.com` and `CERT_NAME=shared` will then use this shared cert. - -#### OCSP Stapling - -To enable OCSP Stapling for a domain, `nginx-proxy` looks for a PEM certificate containing the trusted CA certificate chain at `/etc/nginx/certs/.chain.pem`, where `` is the domain name in the `VIRTUAL_HOST` directive. The format of this file is a concatenation of the public PEM CA certificates starting with the intermediate CA most near the SSL certificate, down to the root CA. This is often referred to as the "SSL Certificate Chain". If found, this filename is passed to the NGINX [`ssl_trusted_certificate` directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate) and OCSP Stapling is enabled. - -#### How SSL Support Works - -The default SSL cipher configuration is based on the [Mozilla intermediate profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29) version 5.0 which should provide compatibility with clients back to Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7, Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9. Note that the DES-based TLS ciphers were removed for security. The configuration also enables HSTS, PFS, OCSP stapling and SSL session caches. Currently TLS 1.2 and 1.3 are supported. - -If you don't require backward compatibility, you can use the [Mozilla modern profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) profile instead by including the environment variable `SSL_POLICY=Mozilla-Modern` to the nginx-proxy container or to your container. This profile is compatible with clients back to Firefox 63, Android 10.0, Chrome 70, Edge 75, Java 11, OpenSSL 1.1.1, Opera 57, and Safari 12.1. Note that this profile is **not** compatible with any version of Internet Explorer. - -Complete list of policies available through the `SSL_POLICY` environment variable, including the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies) and [AWS Classic ELB security policies](https://docs.aws.amazon.com/fr_fr/elasticloadbalancing/latest/classic/elb-security-policy-table.html): - -
    - Mozilla policies - -
    -
    - AWS ELB TLS 1.3 security policies -
      -
    • - AWS-TLS13-1-3-2021-06 -
    • -
    • - AWS-TLS13-1-2-2021-06 -
    • -
    • - AWS-TLS13-1-2-Res-2021-06 -
    • -
    • - AWS-TLS13-1-2-Ext1-2021-06 -
    • -
    • - AWS-TLS13-1-2-Ext2-2021-06 -
    • -
    • - AWS-TLS13-1-1-2021-06 -
    • -
    • - AWS-TLS13-1-0-2021-06 -
    • -
    -
    -
    - AWS ELB FS supported policies -
      -
    • - AWS-FS-1-2-Res-2020-10 -
    • -
    • - AWS-FS-1-2-Res-2019-08 -
    • -
    • - AWS-FS-1-2-2019-08 -
    • -
    • - AWS-FS-1-1-2019-08 -
    • -
    • - AWS-FS-2018-06 -
    • -
    -
    -
    - AWS ELB TLS 1.0 - 1.2 security policies -
      -
    • - AWS-TLS-1-2-Ext-2018-06 -
    • -
    • - AWS-TLS-1-2-2017-01 -
    • -
    • - AWS-TLS-1-1-2017-01 -
    • -
    • - AWS-2016-08 -
    • -
    -
    -
    - AWS Classic ELB security policies -
      -
    • - AWS-2015-05 -
    • -
    • - AWS-2015-03 -
    • -
    • - AWS-2015-02 -
    • -
    -
    -
    - -Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibility but this container provides a 4096 bits key. The [Diffie-Hellman Groups](#diffie-hellman-groups) section details different methods of bypassing this, either globally or per virtual-host. - -The default behavior for the proxy when port 80 and 443 are exposed is as follows: - -* If a virtual host has a usable cert, port 80 will redirect to 443 for that virtual host so that HTTPS is always preferred when available. -* If the virtual host does not have a usable cert, but `default.crt` and `default.key` exist, those will be used as the virtual host's certificate and the client browser will receive a 500 error. -* If the virtual host does not have a usable cert, and `default.crt` and `default.key` do not exist, TLS negotiation will fail (see [Missing Certificate](#missing-certificate) below). - -To serve traffic in both SSL and non-SSL modes without redirecting to SSL, you can include the environment variable `HTTPS_METHOD=noredirect` (the default is `HTTPS_METHOD=redirect`). You can also disable the non-SSL site entirely with `HTTPS_METHOD=nohttp`, or disable the HTTPS site with `HTTPS_METHOD=nohttps`. `HTTPS_METHOD` can be specified on each container for which you want to override the default behavior or on the proxy container to set it globally. If `HTTPS_METHOD=noredirect` is used, Strict Transport Security (HSTS) is disabled to prevent HTTPS users from being redirected by the client. If you cannot get to the HTTP site after changing this setting, your browser has probably cached the HSTS policy and is automatically redirecting you back to HTTPS. You will need to clear your browser's HSTS cache or use an incognito window / different browser. - -By default, [HTTP Strict Transport Security (HSTS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) is enabled with `max-age=31536000` for HTTPS sites. You can disable HSTS with the environment variable `HSTS=off` or use a custom HSTS configuration like `HSTS=max-age=31536000; includeSubDomains; preload`. - -*WARNING*: HSTS will force your users to visit the HTTPS version of your site for the `max-age` time - even if they type in `http://` manually. The only way to get to an HTTP site after receiving an HSTS response is to clear your browser's HSTS cache. - -#### Missing Certificate - -If HTTPS is enabled for a virtual host but its certificate is missing, nginx-proxy will configure nginx to use the default certificate (`default.crt` with `default.key`) and return a 500 error. - -If the default certificate is also missing, nginx-proxy will configure nginx to accept HTTPS connections but fail the TLS negotiation. Client browsers will render a TLS error page. As of March 2023, web browsers display the following error messages: - - * Chrome: - - > This site can't provide a secure connection - > - > example.test sent an invalid response. - > - > Try running Connectivity Diagnostics. - > - > `ERR_SSL_PROTOCOL_ERROR` - - * Firefox: - - > Secure Connection Failed - > - > An error occurred during a connection to example.test. - > Peer reports it experienced an internal error. - > - > Error code: `SSL_ERROR_INTERNAL_ERROR_ALERT` "TLS error". - -### HTTP/2 support - -HTTP/2 is enabled by default and can be disabled if necessary either per-proxied container or globally: - -To disable HTTP/2 for a single proxied container, set the `com.github.nginx-proxy.nginx-proxy.http2.enable` label to `false` on this container. - -To disable HTTP/2 globally set the environment variable `ENABLE_HTTP2` to `false` on the nginx-proxy container. - -More reading on the potential TCP head-of-line blocking issue with HTTP/2: [HTTP/2 Issues](https://www.twilio.com/blog/2017/10/http2-issues.html), [Comparing HTTP/3 vs HTTP/2](https://blog.cloudflare.com/http-3-vs-http-2/) - -### HTTP/3 support - -> **Warning** -> HTTP/3 support [is still considered experimental in nginx](https://www.nginx.com/blog/binary-packages-for-preview-nginx-quic-http3-implementation/) and as such is considered experimental in nginx-proxy too and is disabled by default. [Feedbacks for the HTTP/3 support are welcome in #2271.](https://github.com/nginx-proxy/nginx-proxy/discussions/2271) - -HTTP/3 use the QUIC protocol over UDP (unlike HTTP/1.1 and HTTP/2 which work over TCP), so if you want to use HTTP/3 you'll have to explicitely publish the 443/udp port of the proxy in addition to the 443/tcp port: - -```console -docker run -d -p 80:80 -p 443:443/tcp -p 443:443/udp \ - -v /var/run/docker.sock:/tmp/docker.sock:ro \ - nginxproxy/nginx-proxy -``` - -HTTP/3 can be enabled either per-proxied container or globally: - -To enable HTTP/3 for a single proxied container, set the `com.github.nginx-proxy.nginx-proxy.http3.enable` label to `true` on this container. - -To enable HTTP/3 globally set the environment variable `ENABLE_HTTP3` to `true` on the nginx-proxy container. - -### Basic Authentication Support - -In order to be able to secure your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory -/etc/nginx/htpasswd/$VIRTUAL_HOST - -```console -docker run -d -p 80:80 -p 443:443 \ - -v /path/to/htpasswd:/etc/nginx/htpasswd \ - -v /path/to/certs:/etc/nginx/certs \ - -v /var/run/docker.sock:/tmp/docker.sock:ro \ - nginxproxy/nginx-proxy -``` - -You'll need apache2-utils on the machine where you plan to create the htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/2.2/programs/htpasswd.html) - -### Upstream (Backend) Server HTTP Load Balancing Support - -> **Warning** -> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2195](https://github.com/nginx-proxy/nginx-proxy/discussions/2195). Once we have collected enough feedback we will promote this feature to officially supported. - -If you have multiple containers with the same `VIRTUAL_HOST` and `VIRTUAL_PATH` settings, nginx will spread the load across all of them. To change the load balancing algorithm from nginx's default (round-robin), set the `com.github.nginx-proxy.nginx-proxy.loadbalance` label on one or more of your application containers to the desired load balancing directive. See the [`ngx_http_upstream_module` documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html) for available directives. - -> **Note** -> * Don't forget the terminating semicolon (`;`). -> * If you are using Docker Compose, remember to escape any dollar sign (`$`) characters (`$` becomes `$$`). - -Docker Compose example: - -```yaml -services: - nginx-proxy: - image: nginxproxy/nginx-proxy - ports: - - "80:80" - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - environment: - HTTPS_METHOD: nohttps - myapp: - image: jwilder/whoami - expose: - - "8000" - environment: - VIRTUAL_HOST: myapp.example - VIRTUAL_PORT: "8000" - labels: - com.github.nginx-proxy.nginx-proxy.loadbalance: "hash $$remote_addr;" - deploy: - replicas: 4 -``` - -### Upstream (Backend) Server HTTP Keep-Alive Support - -> **Warning** -> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2194](https://github.com/nginx-proxy/nginx-proxy/discussions/2194). Once we have collected enough feedback we will promote this feature to officially supported. - -To enable HTTP keep-alive between `nginx-proxy` and a backend server, set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container to the desired maximum number of idle connections. See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details. - -### Headers - -By default, `nginx-proxy` forwards all incoming request headers from the client to the backend server unmodified, with the following exceptions: - - * `Connection`: Set to `upgrade` if the client sets the `Upgrade` header, otherwise set to `close`. (Keep-alive between `nginx-proxy` and the backend server is not supported.) - * `Proxy`: Always removed if present. This prevents attackers from using the so-called [httpoxy attack](http://httpoxy.org). There is no legitimate reason for a client to send this header, and there are many vulnerable languages / platforms (`CVE-2016-5385`, `CVE-2016-5386`, `CVE-2016-5387`, `CVE-2016-5388`, `CVE-2016-1000109`, `CVE-2016-1000110`, `CERT-VU#797896`). - * `X-Real-IP`: Set to the client's IP address. - * `X-Forwarded-For`: The client's IP address is appended to the value provided by the client. (If the client did not provide this header, it is set to the client's IP address.) - * `X-Forwarded-Host`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the value of the `Host` header provided by the client. Otherwise, the header is forwarded to the backend server unmodified. - * `X-Forwarded-Proto`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to `http` for plain HTTP connections and `https` for TLS connections. Otherwise, the header is forwarded to the backend server unmodified. - * `X-Forwarded-Ssl`: Set to `on` if the `X-Forwarded-Proto` header sent to the backend server is `https`, otherwise set to `off`. - * `X-Forwarded-Port`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the port of the server that accepted the client's request. Otherwise, the header is forwarded to the backend server unmodified. - * `X-Original-URI`: Set to the original request URI. - -#### Trusting Downstream Proxy Headers - -For legacy compatibility reasons, `nginx-proxy` forwards any client-supplied `X-Forwarded-Proto` (which affects the value of `X-Forwarded-Ssl`), `X-Forwarded-Host`, and `X-Forwarded-Port` headers unchecked and unmodified. To prevent malicious clients from spoofing the protocol, hostname, or port that is perceived by your backend server, you are encouraged to set the `TRUST_DOWNSTREAM_PROXY` value to `false` if: - - * you do not operate a second reverse proxy downstream of `nginx-proxy`, or - * you do operate a second reverse proxy downstream of `nginx-proxy` but that proxy forwards those headers unchecked from untrusted clients. - -The default for `TRUST_DOWNSTREAM_PROXY` may change to `false` in a future version of `nginx-proxy`. If you require it to be enabled, you are encouraged to explicitly set it to `true` to avoid compatibility problems when upgrading. - -### Custom Nginx Configuration - -If you need to configure Nginx beyond what is possible using environment variables, you can provide custom configuration files on either a proxy-wide or per-`VIRTUAL_HOST` basis. - -#### Replacing default proxy settings - -If you want to replace the default proxy settings for the nginx container, add a configuration file at `/etc/nginx/proxy.conf`. A file with the default settings would look like this: - -```Nginx -# HTTP 1.1 support -proxy_http_version 1.1; -proxy_buffering off; -proxy_set_header Host $http_host; -proxy_set_header Upgrade $http_upgrade; -proxy_set_header Connection $proxy_connection; -proxy_set_header X-Real-IP $remote_addr; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host; -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 ""; -``` - -***NOTE***: If you provide this file it will replace the defaults; you may want to check the .tmpl file to make sure you have all of the needed options. - -#### Proxy-wide - -To add settings on a proxy-wide basis, add your configuration file under `/etc/nginx/conf.d` using a name ending in `.conf`. - -This can be done in a derived image by creating the file in a `RUN` command or by `COPY`ing the file into `conf.d`: - -```Dockerfile -FROM nginxproxy/nginx-proxy -RUN { \ - echo 'server_tokens off;'; \ - echo 'client_max_body_size 100m;'; \ - } > /etc/nginx/conf.d/my_proxy.conf -``` - -Or it can be done by mounting in your custom configuration in your `docker run` command: - -```console -docker run -d -p 80:80 -p 443:443 -v /path/to/my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy -``` - -#### Per-VIRTUAL_HOST - -To add settings on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d`. Unlike in the proxy-wide case, which allows multiple config files with any name ending in `.conf`, the per-`VIRTUAL_HOST` file must be named exactly after the `VIRTUAL_HOST`. - -In order to allow virtual hosts to be dynamically configured as backends are added and removed, it makes the most sense to mount an external directory as `/etc/nginx/vhost.d` as opposed to using derived images or mounting individual configuration files. - -For example, if you have a virtual host named `app.example.com`, you could provide a custom configuration for that host as follows: - -```console -docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy -{ echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/app.example.com -``` - -If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink: - -```console -{ echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/www.example.com -ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com -``` - -#### Per-VIRTUAL_HOST default configuration - -If you want most of your virtual hosts to use a default single configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default` file. This file will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}` file associated with it. - -#### Per-VIRTUAL_HOST location configuration - -To add settings to the "location" block on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d` just like the previous section except with the suffix `_location`. - -For example, if you have a virtual host named `app.example.com` and you have configured a proxy_cache `my-cache` in another custom file, you could tell it to use a proxy cache as follows: - -```console -docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy -{ echo 'proxy_cache my-cache;'; echo 'proxy_cache_valid 200 302 60m;'; echo 'proxy_cache_valid 404 1m;' } > /path/to/vhost.d/app.example.com_location -``` - -If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink: - -```console -{ echo 'proxy_cache my-cache;'; echo 'proxy_cache_valid 200 302 60m;'; echo 'proxy_cache_valid 404 1m;' } > /path/to/vhost.d/app.example.com_location -ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com -``` - -#### Per-VIRTUAL_HOST location default configuration - -If you want most of your virtual hosts to use a default single `location` block configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default_location` file. This file will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}_location` file associated with it. - -#### Overriding `location` blocks - -The `${VIRTUAL_HOST}_${PATH_HASH}_location`, `${VIRTUAL_HOST}_location`, and `default_location` files documented above make it possible to *augment* the generated [`location` block(s)](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) in a virtual host. In some circumstances, you may need to *completely override* the `location` block for a particular combination of virtual host and path. To do this, create a file whose name follows this pattern: - -``` -/etc/nginx/vhost.d/${VIRTUAL_HOST}_${PATH_HASH}_location_override -``` - -where `${VIRTUAL_HOST}` is the name of the virtual host (the `VIRTUAL_HOST` environment variable) and `${PATH_HASH}` is the SHA-1 hash of the path, as [described above](#per-virtual_path-location-configuration). - -For convenience, the `_${PATH_HASH}` part can be omitted if the path is `/`: - -``` -/etc/nginx/vhost.d/${VIRTUAL_HOST}_location_override -``` - -When an override file exists, the `location` block that is normally created by `nginx-proxy` is not generated. Instead, the override file is included via the [nginx `include` directive](https://nginx.org/en/docs/ngx_core_module.html#include). - -You are responsible for providing a suitable `location` block in your override file as required for your service. By default, `nginx-proxy` uses the `VIRTUAL_HOST` name as the upstream name for your application's Docker container; see [here](#unhashed-vs-sha1-upstream-names) for details. As an example, if your container has a `VIRTUAL_HOST` value of `app.example.com`, then to override the location block for `/` you would create a file named `/etc/nginx/vhost.d/app.example.com_location_override` that contains something like this: - -``` -location / { - proxy_pass http://app.example.com; -} -``` - -#### Per-VIRTUAL_HOST `server_tokens` configuration -Per virtual-host `servers_tokens` directive can be configured by passing appropriate value to the `SERVER_TOKENS` environment variable. Please see the [nginx http_core module configuration](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) for more details. - -### Unhashed vs SHA1 upstream names - -By default the nginx configuration `upstream` blocks will use this block's corresponding hostname as a predictable name. However, this can cause issues in some setups (see [this issue](https://github.com/nginx-proxy/nginx-proxy/issues/1162)). In those cases you might want to switch to SHA1 names for the `upstream` blocks by setting the `SHA1_UPSTREAM_NAME` environment variable to `true` on the nginx-proxy container. - -Please note that using regular expressions in `VIRTUAL_HOST` will always result in a corresponding `upstream` block with an SHA1 name. - -### Troubleshooting - -If you can't access your `VIRTUAL_HOST`, inspect the generated nginx configuration: - -```console -docker exec nginx -T -``` - -Pay attention to the `upstream` definition blocks, which should look like this: - -```Nginx -# foo.example.com -upstream foo.example.com { - ## Can be connected with "my_network" network - # Exposed ports: [{ tcp } { tcp } ...] - # Default virtual port: - # VIRTUAL_PORT: - # foo - server 172.18.0.9:; - # Fallback entry - server 127.0.0.1 down; -} -``` - -The effective `Port` is retrieved by order of precedence: -1. From the `VIRTUAL_PORT` environment variable -1. From the container's exposed port if there is only one -1. From the default port 80 when none of the above methods apply - -### Contributing - -Before submitting pull requests or issues, please check github to make sure an existing issue or pull request is not already open. - -#### Running Tests Locally - -To run tests, you just need to run the command below: - -```console -make test -``` - -This commands run tests on two variants of the nginx-proxy docker image: Debian and Alpine. - -You can run the tests for each of these images with their respective commands: - -```console -make test-debian -make test-alpine -``` +### Additional documentation -You can learn more about how the test suite works and how to write new tests in the [test/README.md](test/README.md) file. +Please check the [docs section](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs). diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..5162054af --- /dev/null +++ b/docs/README.md @@ -0,0 +1,728 @@ +### Docker Compose + +```yaml +version: '2' + +services: + nginx-proxy: + image: nginxproxy/nginx-proxy + ports: + - "80:80" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + + whoami: + image: jwilder/whoami + expose: + - "8000" + environment: + - VIRTUAL_HOST=whoami.example + - VIRTUAL_PORT=8000 +``` + +```console +docker compose up +curl -H "Host: whoami.example" localhost +``` + +Example output: +```console +I'm 5b129ab83266 +``` + +### IPv6 support + +You can activate the IPv6 support for the nginx-proxy container by passing the value `true` to the `ENABLE_IPV6` environment variable: + +```console +docker run -d -p 80:80 -e ENABLE_IPV6=true -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +``` + +#### Scoped IPv6 Resolvers + +NginX does not support scoped IPv6 resolvers. In [docker-entrypoint.sh](https://github.com/nginx-proxy/nginx-proxy/tree/main/docker-entrypoint.sh) the resolvers are parsed from resolv.conf, but any scoped IPv6 addreses will be removed. + +#### IPv6 NAT + +By default, docker uses IPv6-to-IPv4 NAT. This means all client connections from IPv6 addresses will show docker's internal IPv4 host address. To see true IPv6 client IP addresses, you must [enable IPv6](https://docs.docker.com/config/daemon/ipv6/) and use [ipv6nat](https://github.com/robbertkl/docker-ipv6nat). You must also disable the userland proxy by adding `"userland-proxy": false` to `/etc/docker/daemon.json` and restarting the daemon. + +### Multiple Hosts + +If you need to support multiple virtual hosts for a container, you can separate each entry with commas. For example, `foo.bar.com,baz.bar.com,bar.com` and each host will be setup the same. + +### Virtual Ports + +When your container exposes only one port, nginx-proxy will default to this port, else to port 80. + +If you need to specify a different port, you can set a `VIRTUAL_PORT` env var to select a different one. This variable cannot be set to more than one port. + +For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrieved by order of precedence: +1. From the `VIRTUAL_PORT` environment variable +1. From the container's exposed port if there is only one +1. From the default port 80 when none of the above methods apply + +### 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\..*\.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, 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-Original-URI` 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 having 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`. + +#### 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. + +Exception: If this is set to the string `none`, no default `location /` directive will be generated. This makes it possible for you to provide your own `location /` directive in your [`/etc/nginx/vhost.d/VIRTUAL_HOST`](#per-virtual_host) or [`/etc/nginx/vhost.d/default`](#per-virtual_host-default-configuration) files. + +If unspecified, `DEFAULT_ROOT` defaults to `404`. + +Examples (YAML syntax): + + * `DEFAULT_ROOT: "none"` prevents `nginx-proxy` from generating a default `location /` directive. + * `DEFAULT_ROOT: "418"` returns a 418 error page instead of the normal 404 one. + * `DEFAULT_ROOT: "301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` redirects the client 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. For example, 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 + +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`. + +If you want your `nginx-proxy` container to be attached to a different network, you must pass the `--net=my-network` option in your `docker create` or `docker run` command. At the time of this writing, only a single network can be specified at container creation time. To attach to other networks, you can use the `docker network connect` command after your container is created: + +```console +docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro \ + --name my-nginx-proxy --net my-network nginxproxy/nginx-proxy +docker network connect my-other-network my-nginx-proxy +``` + +In this example, the `my-nginx-proxy` container will be connected to `my-network` and `my-other-network` and will be able to proxy to other containers attached to those networks. + +### Host networking + +`nginx-proxy` is compatible with containers using Docker's [host networking](https://docs.docker.com/network/host/), both with the proxy connected to one or more [bridge network](https://docs.docker.com/network/bridge/) (default or user created) or running in host network mode itself. + +Proxyed containers running in host network mode **must** use the [`VIRTUAL_PORT`](#virtual-ports) environment variable, as this is the only way for `nginx-proxy` to get the correct port (or a port at all) for those containers. + +### Custom external HTTP/HTTPS ports + +If you want to use `nginx-proxy` with different external ports that the default ones of `80` for `HTTP` traffic and `443` for `HTTPS` traffic, you'll have to use the environment variable(s) `HTTP_PORT` and/or `HTTPS_PORT` in addition to the changes to the Docker port mapping. If you change the `HTTPS` port, the redirect for `HTTPS` traffic will also be configured to redirect to the custom port. Typical usage, here with the custom ports `1080` and `10443`: + +```console +docker run -d -p 1080:1080 -p 10443:10443 -e HTTP_PORT=1080 -e HTTPS_PORT=10443 -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +``` + +### Internet vs. Local Network Access + +If you allow traffic from the public internet to access your `nginx-proxy` container, you may want to restrict some containers to the internal network only, so they cannot be accessed from the public internet. On containers that should be restricted to the internal network, you should set the environment variable `NETWORK_ACCESS=internal`. By default, the *internal* network is defined as `127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16`. To change the list of networks considered internal, mount a file on the `nginx-proxy` at `/etc/nginx/network_internal.conf` with these contents, edited to suit your needs: + +```Nginx +# These networks are considered "internal" +allow 127.0.0.0/8; +allow 10.0.0.0/8; +allow 192.168.0.0/16; +allow 172.16.0.0/12; + +# Traffic from all other networks will be rejected +deny all; +``` + +When internal-only access is enabled, external clients will be denied with an `HTTP 403 Forbidden` + +> If there is a load-balancer / reverse proxy in front of `nginx-proxy` that hides the client IP (example: AWS Application/Elastic Load Balancer), you will need to use the nginx `realip` module (already installed) to extract the client's IP from the HTTP request headers. Please see the [nginx realip module configuration](http://nginx.org/en/docs/http/ngx_http_realip_module.html) for more details. This configuration can be added to a new config file and mounted in `/etc/nginx/conf.d/`. + +### SSL Backends + +If you would like the reverse proxy to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container. + +> Note: If you use `VIRTUAL_PROTO=https` and your backend container exposes port 80 and 443, `nginx-proxy` will use HTTPS on port 80. This is almost certainly not what you want, so you should also include `VIRTUAL_PORT=443`. + +### uWSGI Backends + +If you would like to connect to uWSGI backend, set `VIRTUAL_PROTO=uwsgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port. + +### FastCGI Backends + +If you would like to connect to FastCGI backend, set `VIRTUAL_PROTO=fastcgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port. + +### FastCGI File Root Directory + +If you use fastcgi,you can set `VIRTUAL_ROOT=xxx` for your root directory + +### Custom log format + +If you want to use a custom log format, you can set `LOG_FORMAT=xxx` on the proxy container. + +With docker compose take care to escape the `$` character with `$$` to avoid variable interpolation. Example: `$remote_addr` becomes `$$remote_addr`. + +### Default Host + +To set the default host for nginx use the env var `DEFAULT_HOST=foo.bar.com` for example + +```console +docker run -d -p 80:80 -e DEFAULT_HOST=foo.bar.com -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +``` + +nginx-proxy will then redirect all requests to a container where `VIRTUAL_HOST` is set to `DEFAULT_HOST`, if they don't match any (other) `VIRTUAL_HOST`. Using the example above requests without matching `VIRTUAL_HOST` will be redirected to a plain nginx instance after running the following command: + +```console +docker run -d -e VIRTUAL_HOST=foo.bar.com nginx +``` + +### Separate Containers + +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. + +You can demo this pattern with docker compose: + +```console +docker compose --file docker-compose-separate-containers.yml up +curl -H "Host: whoami.example" localhost +``` + +Example output: +```console +I'm 5b129ab83266 +``` + +To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/nginx-proxy/nginx-proxy/blob/main/nginx.tmpl) on your host system. + +First start nginx with a volume: + + +```console +docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx +``` + +Then start the docker-gen container with the shared volume and template: + +```console +docker run --volumes-from nginx \ + -v /var/run/docker.sock:/tmp/docker.sock:ro \ + -v $(pwd):/etc/docker-gen/templates \ + -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. + +```console +docker run -e VIRTUAL_HOST=foo.bar.com ... +``` + +### SSL Support using an ACME CA + +[acme-companion](https://github.com/nginx-proxy/acme-companion) is a lightweight companion container for the nginx-proxy. It allows the automated creation/renewal of SSL certificates using the ACME protocol. + +### SSL Support + +SSL is supported using single host, wildcard and SNI certificates using naming conventions for certificates or optionally specifying a cert name (for SNI) as an environment variable. + +To enable SSL: + +```console +docker run -d -p 80:80 -p 443:443 -v /path/to/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +``` + +The contents of `/path/to/certs` should contain the certificates and private keys for any virtual hosts in use. The certificate and keys should be named after the virtual host with a `.crt` and `.key` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a `foo.bar.com.crt` and `foo.bar.com.key` file in the certs directory. + +If you are running the container in a virtualized environment (Hyper-V, VirtualBox, etc...), /path/to/certs must exist in that environment or be made accessible to that environment. By default, Docker is not able to mount directories on the host machine to containers running in a virtual machine. + +#### Diffie-Hellman Groups + +[RFC7919 groups](https://datatracker.ietf.org/doc/html/rfc7919#appendix-A) with key lengths of 2048, 3072, and 4096 bits are [provided by `nginx-proxy`](https://github.com/nginx-proxy/nginx-proxy/dhparam). The ENV `DHPARAM_BITS` can be set to `2048` or `3072` to change from the default 4096-bit key. The DH key file will be located in the container at `/etc/nginx/dhparam/dhparam.pem`. Mounting a different `dhparam.pem` file at that location will override the RFC7919 key. + +To use custom `dhparam.pem` files per-virtual-host, the files should be named after the virtual host with a `dhparam` suffix and `.pem` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a `foo.bar.com.dhparam.pem` file in the `/etc/nginx/certs` directory. + +> 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 [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`. + +```console +docker run -e DHPARAM_SKIP=true .... +``` + +#### Wildcard Certificates + +Wildcard certificates and keys should be named after the domain name with a `.crt` and `.key` extension. For example `VIRTUAL_HOST=foo.bar.com` would use cert name `bar.com.crt` and `bar.com.key`. + +#### SNI + +If your certificate(s) supports multiple domain names, you can start a container with `CERT_NAME=` to identify the certificate to be used. For example, a certificate for `*.foo.com` and `*.bar.com` could be named `shared.crt` and `shared.key`. A container running with `VIRTUAL_HOST=foo.bar.com` and `CERT_NAME=shared` will then use this shared cert. + +#### OCSP Stapling + +To enable OCSP Stapling for a domain, `nginx-proxy` looks for a PEM certificate containing the trusted CA certificate chain at `/etc/nginx/certs/.chain.pem`, where `` is the domain name in the `VIRTUAL_HOST` directive. The format of this file is a concatenation of the public PEM CA certificates starting with the intermediate CA most near the SSL certificate, down to the root CA. This is often referred to as the "SSL Certificate Chain". If found, this filename is passed to the NGINX [`ssl_trusted_certificate` directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate) and OCSP Stapling is enabled. + +#### How SSL Support Works + +The default SSL cipher configuration is based on the [Mozilla intermediate profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29) version 5.0 which should provide compatibility with clients back to Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7, Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9. Note that the DES-based TLS ciphers were removed for security. The configuration also enables HSTS, PFS, OCSP stapling and SSL session caches. Currently TLS 1.2 and 1.3 are supported. + +If you don't require backward compatibility, you can use the [Mozilla modern profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) profile instead by including the environment variable `SSL_POLICY=Mozilla-Modern` to the nginx-proxy container or to your container. This profile is compatible with clients back to Firefox 63, Android 10.0, Chrome 70, Edge 75, Java 11, OpenSSL 1.1.1, Opera 57, and Safari 12.1. Note that this profile is **not** compatible with any version of Internet Explorer. + +Complete list of policies available through the `SSL_POLICY` environment variable, including the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies) and [AWS Classic ELB security policies](https://docs.aws.amazon.com/fr_fr/elasticloadbalancing/latest/classic/elb-security-policy-table.html): + +
    + Mozilla policies + +
    +
    + AWS ELB TLS 1.3 security policies +
      +
    • + AWS-TLS13-1-3-2021-06 +
    • +
    • + AWS-TLS13-1-2-2021-06 +
    • +
    • + AWS-TLS13-1-2-Res-2021-06 +
    • +
    • + AWS-TLS13-1-2-Ext1-2021-06 +
    • +
    • + AWS-TLS13-1-2-Ext2-2021-06 +
    • +
    • + AWS-TLS13-1-1-2021-06 +
    • +
    • + AWS-TLS13-1-0-2021-06 +
    • +
    +
    +
    + AWS ELB FS supported policies +
      +
    • + AWS-FS-1-2-Res-2020-10 +
    • +
    • + AWS-FS-1-2-Res-2019-08 +
    • +
    • + AWS-FS-1-2-2019-08 +
    • +
    • + AWS-FS-1-1-2019-08 +
    • +
    • + AWS-FS-2018-06 +
    • +
    +
    +
    + AWS ELB TLS 1.0 - 1.2 security policies +
      +
    • + AWS-TLS-1-2-Ext-2018-06 +
    • +
    • + AWS-TLS-1-2-2017-01 +
    • +
    • + AWS-TLS-1-1-2017-01 +
    • +
    • + AWS-2016-08 +
    • +
    +
    +
    + AWS Classic ELB security policies +
      +
    • + AWS-2015-05 +
    • +
    • + AWS-2015-03 +
    • +
    • + AWS-2015-02 +
    • +
    +
    +
    + +Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibility but this container provides a 4096 bits key. The [Diffie-Hellman Groups](#diffie-hellman-groups) section details different methods of bypassing this, either globally or per virtual-host. + +The default behavior for the proxy when port 80 and 443 are exposed is as follows: + +* If a virtual host has a usable cert, port 80 will redirect to 443 for that virtual host so that HTTPS is always preferred when available. +* If the virtual host does not have a usable cert, but `default.crt` and `default.key` exist, those will be used as the virtual host's certificate and the client browser will receive a 500 error. +* If the virtual host does not have a usable cert, and `default.crt` and `default.key` do not exist, TLS negotiation will fail (see [Missing Certificate](#missing-certificate) below). + +To serve traffic in both SSL and non-SSL modes without redirecting to SSL, you can include the environment variable `HTTPS_METHOD=noredirect` (the default is `HTTPS_METHOD=redirect`). You can also disable the non-SSL site entirely with `HTTPS_METHOD=nohttp`, or disable the HTTPS site with `HTTPS_METHOD=nohttps`. `HTTPS_METHOD` can be specified on each container for which you want to override the default behavior or on the proxy container to set it globally. If `HTTPS_METHOD=noredirect` is used, Strict Transport Security (HSTS) is disabled to prevent HTTPS users from being redirected by the client. If you cannot get to the HTTP site after changing this setting, your browser has probably cached the HSTS policy and is automatically redirecting you back to HTTPS. You will need to clear your browser's HSTS cache or use an incognito window / different browser. + +By default, [HTTP Strict Transport Security (HSTS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) is enabled with `max-age=31536000` for HTTPS sites. You can disable HSTS with the environment variable `HSTS=off` or use a custom HSTS configuration like `HSTS=max-age=31536000; includeSubDomains; preload`. + +*WARNING*: HSTS will force your users to visit the HTTPS version of your site for the `max-age` time - even if they type in `http://` manually. The only way to get to an HTTP site after receiving an HSTS response is to clear your browser's HSTS cache. + +#### Missing Certificate + +If HTTPS is enabled for a virtual host but its certificate is missing, nginx-proxy will configure nginx to use the default certificate (`default.crt` with `default.key`) and return a 500 error. + +If the default certificate is also missing, nginx-proxy will configure nginx to accept HTTPS connections but fail the TLS negotiation. Client browsers will render a TLS error page. As of March 2023, web browsers display the following error messages: + + * Chrome: + + > This site can't provide a secure connection + > + > example.test sent an invalid response. + > + > Try running Connectivity Diagnostics. + > + > `ERR_SSL_PROTOCOL_ERROR` + + * Firefox: + + > Secure Connection Failed + > + > An error occurred during a connection to example.test. + > Peer reports it experienced an internal error. + > + > Error code: `SSL_ERROR_INTERNAL_ERROR_ALERT` "TLS error". + +### HTTP/2 support + +HTTP/2 is enabled by default and can be disabled if necessary either per-proxied container or globally: + +To disable HTTP/2 for a single proxied container, set the `com.github.nginx-proxy.nginx-proxy.http2.enable` label to `false` on this container. + +To disable HTTP/2 globally set the environment variable `ENABLE_HTTP2` to `false` on the nginx-proxy container. + +More reading on the potential TCP head-of-line blocking issue with HTTP/2: [HTTP/2 Issues](https://www.twilio.com/blog/2017/10/http2-issues.html), [Comparing HTTP/3 vs HTTP/2](https://blog.cloudflare.com/http-3-vs-http-2/) + +### HTTP/3 support + +> **Warning** +> HTTP/3 support [is still considered experimental in nginx](https://www.nginx.com/blog/binary-packages-for-preview-nginx-quic-http3-implementation/) and as such is considered experimental in nginx-proxy too and is disabled by default. [Feedbacks for the HTTP/3 support are welcome in #2271.](https://github.com/nginx-proxy/nginx-proxy/discussions/2271) + +HTTP/3 use the QUIC protocol over UDP (unlike HTTP/1.1 and HTTP/2 which work over TCP), so if you want to use HTTP/3 you'll have to explicitely publish the 443/udp port of the proxy in addition to the 443/tcp port: + +```console +docker run -d -p 80:80 -p 443:443/tcp -p 443:443/udp \ + -v /var/run/docker.sock:/tmp/docker.sock:ro \ + nginxproxy/nginx-proxy +``` + +HTTP/3 can be enabled either per-proxied container or globally: + +To enable HTTP/3 for a single proxied container, set the `com.github.nginx-proxy.nginx-proxy.http3.enable` label to `true` on this container. + +To enable HTTP/3 globally set the environment variable `ENABLE_HTTP3` to `true` on the nginx-proxy container. + +### Basic Authentication Support + +In order to be able to secure your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory +/etc/nginx/htpasswd/$VIRTUAL_HOST + +```console +docker run -d -p 80:80 -p 443:443 \ + -v /path/to/htpasswd:/etc/nginx/htpasswd \ + -v /path/to/certs:/etc/nginx/certs \ + -v /var/run/docker.sock:/tmp/docker.sock:ro \ + nginxproxy/nginx-proxy +``` + +You'll need apache2-utils on the machine where you plan to create the htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/2.2/programs/htpasswd.html) + +### Upstream (Backend) Server HTTP Load Balancing Support + +> **Warning** +> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2195](https://github.com/nginx-proxy/nginx-proxy/discussions/2195). Once we have collected enough feedback we will promote this feature to officially supported. + +If you have multiple containers with the same `VIRTUAL_HOST` and `VIRTUAL_PATH` settings, nginx will spread the load across all of them. To change the load balancing algorithm from nginx's default (round-robin), set the `com.github.nginx-proxy.nginx-proxy.loadbalance` label on one or more of your application containers to the desired load balancing directive. See the [`ngx_http_upstream_module` documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html) for available directives. + +> **Note** +> * Don't forget the terminating semicolon (`;`). +> * If you are using Docker Compose, remember to escape any dollar sign (`$`) characters (`$` becomes `$$`). + +Docker Compose example: + +```yaml +services: + nginx-proxy: + image: nginxproxy/nginx-proxy + ports: + - "80:80" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + HTTPS_METHOD: nohttps + myapp: + image: jwilder/whoami + expose: + - "8000" + environment: + VIRTUAL_HOST: myapp.example + VIRTUAL_PORT: "8000" + labels: + com.github.nginx-proxy.nginx-proxy.loadbalance: "hash $$remote_addr;" + deploy: + replicas: 4 +``` + +### Upstream (Backend) Server HTTP Keep-Alive Support + +> **Warning** +> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2194](https://github.com/nginx-proxy/nginx-proxy/discussions/2194). Once we have collected enough feedback we will promote this feature to officially supported. + +To enable HTTP keep-alive between `nginx-proxy` and a backend server, set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container to the desired maximum number of idle connections. See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details. + +### Headers + +By default, `nginx-proxy` forwards all incoming request headers from the client to the backend server unmodified, with the following exceptions: + + * `Connection`: Set to `upgrade` if the client sets the `Upgrade` header, otherwise set to `close`. (Keep-alive between `nginx-proxy` and the backend server is not supported.) + * `Proxy`: Always removed if present. This prevents attackers from using the so-called [httpoxy attack](http://httpoxy.org). There is no legitimate reason for a client to send this header, and there are many vulnerable languages / platforms (`CVE-2016-5385`, `CVE-2016-5386`, `CVE-2016-5387`, `CVE-2016-5388`, `CVE-2016-1000109`, `CVE-2016-1000110`, `CERT-VU#797896`). + * `X-Real-IP`: Set to the client's IP address. + * `X-Forwarded-For`: The client's IP address is appended to the value provided by the client. (If the client did not provide this header, it is set to the client's IP address.) + * `X-Forwarded-Host`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the value of the `Host` header provided by the client. Otherwise, the header is forwarded to the backend server unmodified. + * `X-Forwarded-Proto`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to `http` for plain HTTP connections and `https` for TLS connections. Otherwise, the header is forwarded to the backend server unmodified. + * `X-Forwarded-Ssl`: Set to `on` if the `X-Forwarded-Proto` header sent to the backend server is `https`, otherwise set to `off`. + * `X-Forwarded-Port`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the port of the server that accepted the client's request. Otherwise, the header is forwarded to the backend server unmodified. + * `X-Original-URI`: Set to the original request URI. + +#### Trusting Downstream Proxy Headers + +For legacy compatibility reasons, `nginx-proxy` forwards any client-supplied `X-Forwarded-Proto` (which affects the value of `X-Forwarded-Ssl`), `X-Forwarded-Host`, and `X-Forwarded-Port` headers unchecked and unmodified. To prevent malicious clients from spoofing the protocol, hostname, or port that is perceived by your backend server, you are encouraged to set the `TRUST_DOWNSTREAM_PROXY` value to `false` if: + + * you do not operate a second reverse proxy downstream of `nginx-proxy`, or + * you do operate a second reverse proxy downstream of `nginx-proxy` but that proxy forwards those headers unchecked from untrusted clients. + +The default for `TRUST_DOWNSTREAM_PROXY` may change to `false` in a future version of `nginx-proxy`. If you require it to be enabled, you are encouraged to explicitly set it to `true` to avoid compatibility problems when upgrading. + +### Custom Nginx Configuration + +If you need to configure Nginx beyond what is possible using environment variables, you can provide custom configuration files on either a proxy-wide or per-`VIRTUAL_HOST` basis. + +#### Replacing default proxy settings + +If you want to replace the default proxy settings for the nginx container, add a configuration file at `/etc/nginx/proxy.conf`. A file with the default settings would look like this: + +```Nginx +# HTTP 1.1 support +proxy_http_version 1.1; +proxy_buffering off; +proxy_set_header Host $http_host; +proxy_set_header Upgrade $http_upgrade; +proxy_set_header Connection $proxy_connection; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host; +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 ""; +``` + +***NOTE***: If you provide this file it will replace the defaults; you may want to check the .tmpl file to make sure you have all of the needed options. + +#### Proxy-wide + +To add settings on a proxy-wide basis, add your configuration file under `/etc/nginx/conf.d` using a name ending in `.conf`. + +This can be done in a derived image by creating the file in a `RUN` command or by `COPY`ing the file into `conf.d`: + +```Dockerfile +FROM nginxproxy/nginx-proxy +RUN { \ + echo 'server_tokens off;'; \ + echo 'client_max_body_size 100m;'; \ + } > /etc/nginx/conf.d/my_proxy.conf +``` + +Or it can be done by mounting in your custom configuration in your `docker run` command: + +```console +docker run -d -p 80:80 -p 443:443 -v /path/to/my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +``` + +#### Per-VIRTUAL_HOST + +To add settings on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d`. Unlike in the proxy-wide case, which allows multiple config files with any name ending in `.conf`, the per-`VIRTUAL_HOST` file must be named exactly after the `VIRTUAL_HOST`. + +In order to allow virtual hosts to be dynamically configured as backends are added and removed, it makes the most sense to mount an external directory as `/etc/nginx/vhost.d` as opposed to using derived images or mounting individual configuration files. + +For example, if you have a virtual host named `app.example.com`, you could provide a custom configuration for that host as follows: + +```console +docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +{ echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/app.example.com +``` + +If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink: + +```console +{ echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/www.example.com +ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com +``` + +#### Per-VIRTUAL_HOST default configuration + +If you want most of your virtual hosts to use a default single configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default` file. This file will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}` file associated with it. + +#### Per-VIRTUAL_HOST location configuration + +To add settings to the "location" block on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d` just like the previous section except with the suffix `_location`. + +For example, if you have a virtual host named `app.example.com` and you have configured a proxy_cache `my-cache` in another custom file, you could tell it to use a proxy cache as follows: + +```console +docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy +{ echo 'proxy_cache my-cache;'; echo 'proxy_cache_valid 200 302 60m;'; echo 'proxy_cache_valid 404 1m;' } > /path/to/vhost.d/app.example.com_location +``` + +If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink: + +```console +{ echo 'proxy_cache my-cache;'; echo 'proxy_cache_valid 200 302 60m;'; echo 'proxy_cache_valid 404 1m;' } > /path/to/vhost.d/app.example.com_location +ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com +``` + +#### Per-VIRTUAL_HOST location default configuration + +If you want most of your virtual hosts to use a default single `location` block configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default_location` file. This file will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}_location` file associated with it. + +#### Overriding `location` blocks + +The `${VIRTUAL_HOST}_${PATH_HASH}_location`, `${VIRTUAL_HOST}_location`, and `default_location` files documented above make it possible to *augment* the generated [`location` block(s)](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) in a virtual host. In some circumstances, you may need to *completely override* the `location` block for a particular combination of virtual host and path. To do this, create a file whose name follows this pattern: + +``` +/etc/nginx/vhost.d/${VIRTUAL_HOST}_${PATH_HASH}_location_override +``` + +where `${VIRTUAL_HOST}` is the name of the virtual host (the `VIRTUAL_HOST` environment variable) and `${PATH_HASH}` is the SHA-1 hash of the path, as [described above](#per-virtual_path-location-configuration). + +For convenience, the `_${PATH_HASH}` part can be omitted if the path is `/`: + +``` +/etc/nginx/vhost.d/${VIRTUAL_HOST}_location_override +``` + +When an override file exists, the `location` block that is normally created by `nginx-proxy` is not generated. Instead, the override file is included via the [nginx `include` directive](https://nginx.org/en/docs/ngx_core_module.html#include). + +You are responsible for providing a suitable `location` block in your override file as required for your service. By default, `nginx-proxy` uses the `VIRTUAL_HOST` name as the upstream name for your application's Docker container; see [here](#unhashed-vs-sha1-upstream-names) for details. As an example, if your container has a `VIRTUAL_HOST` value of `app.example.com`, then to override the location block for `/` you would create a file named `/etc/nginx/vhost.d/app.example.com_location_override` that contains something like this: + +``` +location / { + proxy_pass http://app.example.com; +} +``` + +#### Per-VIRTUAL_HOST `server_tokens` configuration +Per virtual-host `servers_tokens` directive can be configured by passing appropriate value to the `SERVER_TOKENS` environment variable. Please see the [nginx http_core module configuration](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) for more details. + +### Unhashed vs SHA1 upstream names + +By default the nginx configuration `upstream` blocks will use this block's corresponding hostname as a predictable name. However, this can cause issues in some setups (see [this issue](https://github.com/nginx-proxy/nginx-proxy/issues/1162)). In those cases you might want to switch to SHA1 names for the `upstream` blocks by setting the `SHA1_UPSTREAM_NAME` environment variable to `true` on the nginx-proxy container. + +Please note that using regular expressions in `VIRTUAL_HOST` will always result in a corresponding `upstream` block with an SHA1 name. + +### Troubleshooting + +If you can't access your `VIRTUAL_HOST`, inspect the generated nginx configuration: + +```console +docker exec nginx -T +``` + +Pay attention to the `upstream` definition blocks, which should look like this: + +```Nginx +# foo.example.com +upstream foo.example.com { + ## Can be connected with "my_network" network + # Exposed ports: [{ tcp } { tcp } ...] + # Default virtual port: + # VIRTUAL_PORT: + # foo + server 172.18.0.9:; + # Fallback entry + server 127.0.0.1 down; +} +``` + +The effective `Port` is retrieved by order of precedence: +1. From the `VIRTUAL_PORT` environment variable +1. From the container's exposed port if there is only one +1. From the default port 80 when none of the above methods apply + +### Contributing + +Before submitting pull requests or issues, please check github to make sure an existing issue or pull request is not already open. + +#### Running Tests Locally + +To run tests, you just need to run the command below: + +```console +make test +``` + +This commands run tests on two variants of the nginx-proxy docker image: Debian and Alpine. + +You can run the tests for each of these images with their respective commands: + +```console +make test-debian +make test-alpine +``` + +You can learn more about how the test suite works and how to write new tests in the [test/README.md](https://github.com/nginx-proxy/nginx-proxy/tree/main/test/README.md) file. From 4a8aa5db671a470f044e4c787bd28bf389afe62a Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 25 Dec 2023 11:27:22 +0100 Subject: [PATCH 30/58] docs: fix two links in updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48d513f07..edb3bb280 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ The containers being proxied must : - [expose](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) the port to be proxied, either by using the `EXPOSE` directive in their `Dockerfile` or by using the `--expose` flag to `docker run` or `docker create`. - share at least one Docker network with the nginx-proxy container: 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. -Note: providing a port number in `VIRTUAL_HOST` isn't suported, please see [virtual ports](https://github.com/nginx-proxy/nginx-proxy/docs#virtual-ports) or [custom external HTTP/HTTPS ports](https://github.com/nginx-proxy/nginx-proxy/docs#custom-external-httphttps-ports) depending on what you want to achieve. +Note: providing a port number in `VIRTUAL_HOST` isn't suported, please see [virtual ports](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#virtual-ports) or [custom external HTTP/HTTPS ports](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#custom-external-httphttps-ports) depending on what you want to achieve. ### Image variants From 5c1db95551e5a5ac8ef412df082b042da54453ce Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 25 Dec 2023 17:27:34 +0100 Subject: [PATCH 31/58] feat: enable proxy_buffering --- docs/README.md | 1 - nginx.tmpl | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 5162054af..b2f87c4fd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -556,7 +556,6 @@ If you want to replace the default proxy settings for the nginx container, add a ```Nginx # HTTP 1.1 support proxy_http_version 1.1; -proxy_buffering off; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; diff --git a/nginx.tmpl b/nginx.tmpl index 66324ff8d..08606b9da 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -402,7 +402,6 @@ include /etc/nginx/proxy.conf; {{- else }} # HTTP 1.1 support proxy_http_version 1.1; -proxy_buffering off; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; From de4cb3d2b06171825e0df97414e1c3ac80e1cc73 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 25 Dec 2023 19:16:10 +0100 Subject: [PATCH 32/58] refactor: move nginx daemon off to procfile --- Dockerfile.alpine | 3 +-- Dockerfile.debian | 3 +-- app/Procfile | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 2fb2cdaef..b94f06737 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -21,8 +21,7 @@ RUN apk add --no-cache --virtual .run-deps \ && update-ca-certificates # Configure Nginx -RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ - && sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf \ +RUN 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 \ && mkdir -p '/etc/nginx/dhparam' diff --git a/Dockerfile.debian b/Dockerfile.debian index 2b7801ccc..99e16d9fa 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -20,8 +20,7 @@ RUN apt-get update \ && rm -r /var/lib/apt/lists/* # Configure Nginx -RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ - && sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf \ +RUN 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 \ && mkdir -p '/etc/nginx/dhparam' diff --git a/app/Procfile b/app/Procfile index 29fe16627..f23e0f4fd 100644 --- a/app/Procfile +++ b/app/Procfile @@ -1,2 +1,2 @@ dockergen: docker-gen -watch -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf -nginx: nginx +nginx: nginx -g "daemon off;" From 758b43a5b2c71501b7683f094be97eb8755a0a51 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 25 Dec 2023 19:18:00 +0100 Subject: [PATCH 33/58] refactor: remove unneeded nginx.conf modification the upstream nginx.conf already has "worker_processes auto;" --- Dockerfile.alpine | 3 +-- Dockerfile.debian | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index b94f06737..f402e05df 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -21,8 +21,7 @@ RUN apk add --no-cache --virtual .run-deps \ && update-ca-certificates # Configure Nginx -RUN 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 \ +RUN sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ && mkdir -p '/etc/nginx/dhparam' # Install Forego + docker-gen diff --git a/Dockerfile.debian b/Dockerfile.debian index 99e16d9fa..e13f324bc 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -20,8 +20,7 @@ RUN apt-get update \ && rm -r /var/lib/apt/lists/* # Configure Nginx -RUN 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 \ +RUN sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ && mkdir -p '/etc/nginx/dhparam' # Install Forego + docker-gen From eb9fca85cf50f0d42a7dcd0741e26d3c3674c414 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 25 Dec 2023 19:19:57 +0100 Subject: [PATCH 34/58] refactor: remove already present or unneeded dependencies --- Dockerfile.alpine | 6 +----- Dockerfile.debian | 6 ------ 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index f402e05df..864aed56f 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -14,11 +14,7 @@ ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \ DOCKER_HOST=unix:///tmp/docker.sock # Install dependencies -RUN apk add --no-cache --virtual .run-deps \ - bash \ - ca-certificates \ - openssl \ - && update-ca-certificates +RUN apk add --no-cache --virtual .run-deps bash # Configure Nginx RUN sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ diff --git a/Dockerfile.debian b/Dockerfile.debian index e13f324bc..69114bc8e 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -13,12 +13,6 @@ ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \ DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \ DOCKER_HOST=unix:///tmp/docker.sock -# Install/update certificates -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends ca-certificates \ - && apt-get clean \ - && rm -r /var/lib/apt/lists/* - # Configure Nginx RUN sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ && mkdir -p '/etc/nginx/dhparam' From 051c8a510576e70f841f6a07e8ff236df4730d55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 19:45:00 +0000 Subject: [PATCH 35/58] build: bump nginxproxy/docker-gen from 0.11.0-debian to 0.11.1-debian Bumps nginxproxy/docker-gen from 0.11.0-debian to 0.11.1-debian. --- updated-dependencies: - dependency-name: nginxproxy/docker-gen dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile.alpine | 2 +- Dockerfile.debian | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 864aed56f..323480765 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,4 +1,4 @@ -FROM nginxproxy/docker-gen:0.11.0 AS docker-gen +FROM nginxproxy/docker-gen:0.11.1 AS docker-gen FROM nginxproxy/forego:0.17.3 AS forego diff --git a/Dockerfile.debian b/Dockerfile.debian index 69114bc8e..b170653bc 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -1,4 +1,4 @@ -FROM nginxproxy/docker-gen:0.11.0-debian AS docker-gen +FROM nginxproxy/docker-gen:0.11.1-debian AS docker-gen FROM nginxproxy/forego:0.17.3-debian AS forego From 47ee75d7800eeaa9a151fb24e53ab79ca1430373 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 20:12:56 +0000 Subject: [PATCH 36/58] build: bump nginxproxy/forego from 0.17.3-debian to 0.18.1-debian Bumps nginxproxy/forego from 0.17.3-debian to 0.18.1-debian. --- updated-dependencies: - dependency-name: nginxproxy/forego dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Dockerfile.alpine | 2 +- Dockerfile.debian | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 323480765..ffdd52cda 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,6 +1,6 @@ FROM nginxproxy/docker-gen:0.11.1 AS docker-gen -FROM nginxproxy/forego:0.17.3 AS forego +FROM nginxproxy/forego:0.18.1 AS forego # Build the final image FROM nginx:1.25.3-alpine diff --git a/Dockerfile.debian b/Dockerfile.debian index b170653bc..2d767fe80 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -1,6 +1,6 @@ FROM nginxproxy/docker-gen:0.11.1-debian AS docker-gen -FROM nginxproxy/forego:0.17.3-debian AS forego +FROM nginxproxy/forego:0.18.1-debian AS forego # Build the final image FROM nginx:1.25.3 From beeb80732aba685cd4534facbe4d5477acf8350b Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 25 Dec 2023 21:19:02 +0100 Subject: [PATCH 37/58] docs: mention color disabling --- docs/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/README.md b/docs/README.md index b2f87c4fd..f59d2aad8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -674,6 +674,18 @@ By default the nginx configuration `upstream` blocks will use this block's corre Please note that using regular expressions in `VIRTUAL_HOST` will always result in a corresponding `upstream` block with an SHA1 name. +### Disabling colors in the log output + +To remove colors from the log output, set the [`NO_COLOR` environment variable to any value other than an empty string](https://no-color.org/) on the nginx-proxy container. + +```console +docker run --detach \ + --publish 80:80 \ + --env NO_COLOR=1 \ + --volume /var/run/docker.sock:/tmp/docker.sock:ro \ + nginxproxy/nginx-proxy +``` + ### Troubleshooting If you can't access your `VIRTUAL_HOST`, inspect the generated nginx configuration: From 26db13387e26385639f9394c58b2bb4c116bc037 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 26 Dec 2023 17:58:24 +0100 Subject: [PATCH 38/58] refactor: explicitely default keepalive to disabled --- nginx.tmpl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 08606b9da..b7a3b9ae2 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -249,7 +249,7 @@ {{- if exists $override }} include {{ $override }}; {{- else }} - {{- $keepalive := first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive")) }} + {{- $keepalive := coalesce (first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive"))) "disabled" }} location {{ .Path }} { {{- if eq .NetworkTag "internal" }} # Only allow traffic from internal clients @@ -263,14 +263,14 @@ root {{ trim .VhostRoot }}; include fastcgi_params; fastcgi_pass {{ trim .Upstream }}; - {{- if $keepalive }} + {{- if ne $keepalive "disabled" }} fastcgi_keep_conn on; {{- end }} {{- else if eq .Proto "grpc" }} grpc_pass {{ trim .Proto }}://{{ trim .Upstream }}; {{- else }} proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}{{ trim .Dest }}; - set $upstream_keepalive {{ if $keepalive }}true{{ else }}false{{ end }}; + set $upstream_keepalive {{ if ne $keepalive "disabled" }}true{{ else }}false{{ end }}; {{- end }} {{- if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }} @@ -315,8 +315,8 @@ upstream {{ .Upstream }} { # Fallback entry server 127.0.0.1 down; {{- end }} - {{- $keepalive := first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive")) }} - {{- if $keepalive }} + {{- $keepalive := coalesce (first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive"))) "disabled" }} + {{- if ne $keepalive "disabled" }} keepalive {{ $keepalive }}; {{- end }} } From 7ce72d59a98522ae1c99258ee7ec37fd8fec19d0 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 26 Dec 2023 18:18:00 +0100 Subject: [PATCH 39/58] feat: add auto keepalive setting --- nginx.tmpl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index b7a3b9ae2..9477928d0 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -292,6 +292,7 @@ {{- define "upstream" }} upstream {{ .Upstream }} { {{- $server_found := false }} + {{- $servers := 0 }} {{- $loadbalance := first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.loadbalance")) }} {{- if $loadbalance }} # From the container's loadbalance label: @@ -307,6 +308,7 @@ upstream {{ .Upstream }} { {{- $port := $args.port }} {{- if $ip }} {{- $server_found = true }} + {{- $servers = add1 $servers }} server {{ $ip }}:{{ $port }}; {{- end }} {{- end }} @@ -316,8 +318,12 @@ upstream {{ .Upstream }} { server 127.0.0.1 down; {{- end }} {{- $keepalive := coalesce (first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive"))) "disabled" }} - {{- if ne $keepalive "disabled" }} + {{- if and (ne $keepalive "disabled") (gt $servers 0) }} + {{- if eq $keepalive "auto" }} + keepalive {{ mul $servers 2 }}; + {{- else }} keepalive {{ $keepalive }}; + {{- end }} {{- end }} } {{- end }} From d56e8f1d8a6851520c2e7cf3a9e722ec13aaa0eb Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 26 Dec 2023 18:43:05 +0100 Subject: [PATCH 40/58] refactor: $server_found and $servers aren't both needed --- nginx.tmpl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 9477928d0..e187a0fb7 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -291,7 +291,6 @@ {{- define "upstream" }} upstream {{ .Upstream }} { - {{- $server_found := false }} {{- $servers := 0 }} {{- $loadbalance := first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.loadbalance")) }} {{- if $loadbalance }} @@ -307,13 +306,12 @@ upstream {{ .Upstream }} { {{- template "container_port" $args }} {{- $port := $args.port }} {{- if $ip }} - {{- $server_found = true }} {{- $servers = add1 $servers }} server {{ $ip }}:{{ $port }}; {{- end }} {{- end }} {{- /* nginx-proxy/nginx-proxy#1105 */}} - {{- if not $server_found }} + {{- if lt $servers 1 }} # Fallback entry server 127.0.0.1 down; {{- end }} From 443ee5202c25972a97f535089155c90de1be6b7e Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 26 Dec 2023 18:52:43 +0100 Subject: [PATCH 41/58] test: do we get desired number of idle keepalive connections --- test/test_keepalive.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_keepalive.py b/test/test_keepalive.py index b5b83539c..2f78c3a99 100644 --- a/test/test_keepalive.py +++ b/test/test_keepalive.py @@ -20,6 +20,9 @@ def test_keepalive_disabled_other_headers_ok(docker_compose, nginxproxy): assert re.search(fr'(?m)^(?i:X-Real-IP): ', r.text) def test_keepalive_enabled(docker_compose, nginxproxy): + conf = nginxproxy.get_conf().decode('ASCII') + assert re.search(r"keepalive 64\;", conf) + r = nginxproxy.get("http://keepalive-enabled.nginx-proxy.test/headers") assert r.status_code == 200 assert not re.search(fr'(?m)^(?i:Connection):', r.text) From 2aa35aa6371895affa0c90afe191a4f823cfcb42 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 26 Dec 2023 19:07:09 +0100 Subject: [PATCH 42/58] tests: keepalive auto setting --- test/test_keepalive.py | 8 ++++++++ test/test_keepalive.yml | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/test/test_keepalive.py b/test/test_keepalive.py index 2f78c3a99..c007cf1cb 100644 --- a/test/test_keepalive.py +++ b/test/test_keepalive.py @@ -27,6 +27,14 @@ def test_keepalive_enabled(docker_compose, nginxproxy): assert r.status_code == 200 assert not re.search(fr'(?m)^(?i:Connection):', r.text) +def test_keepalive_auto_enabled(docker_compose, nginxproxy): + conf = nginxproxy.get_conf().decode('ASCII') + assert re.search(r"keepalive 8\;", conf) + + r = nginxproxy.get("http://keepalive-auto.nginx-proxy.test/headers") + assert r.status_code == 200 + assert not re.search(fr'(?m)^(?i:Connection):', r.text) + def test_keepalive_enabled_other_headers_ok(docker_compose, nginxproxy): """See the docstring for the disabled case above.""" r = nginxproxy.get("http://keepalive-enabled.nginx-proxy.test/headers") diff --git a/test/test_keepalive.yml b/test/test_keepalive.yml index 62f5b252f..6da66f0b3 100644 --- a/test/test_keepalive.yml +++ b/test/test_keepalive.yml @@ -18,6 +18,19 @@ services: VIRTUAL_HOST: keepalive-enabled.nginx-proxy.test labels: com.github.nginx-proxy.nginx-proxy.keepalive: "64" + + keepalive-auto: + image: web + deploy: + mode: replicated + replicas: 4 + expose: + - "80" + environment: + WEB_PORTS: 80 + VIRTUAL_HOST: keepalive-auto.nginx-proxy.test + labels: + com.github.nginx-proxy.nginx-proxy.keepalive: "auto" sut: image: nginxproxy/nginx-proxy:test From d12689cd52021ac28a1cb045fe8e9e430bb4f364 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Tue, 26 Dec 2023 19:10:42 +0100 Subject: [PATCH 43/58] docs: keepalive auto setting --- docs/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index f59d2aad8..431fe6027 100644 --- a/docs/README.md +++ b/docs/README.md @@ -520,7 +520,9 @@ services: > **Warning** > This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2194](https://github.com/nginx-proxy/nginx-proxy/discussions/2194). Once we have collected enough feedback we will promote this feature to officially supported. -To enable HTTP keep-alive between `nginx-proxy` and a backend server, set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container to the desired maximum number of idle connections. See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details. +To enable HTTP keep-alive between `nginx-proxy` and backend server(s), set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container either to `auto` or to the desired maximum number of idle connections. The `auto` setting will dynamically set the maximum number of idle connections to twice the number of servers listed in the corresponding `upstream{}` block, [per nginx recommendation](https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#no-keepalives). + +See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details. ### Headers From e2bd0d63654c012b4e06d8952cdd383b75b32f81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 04:39:54 +0000 Subject: [PATCH 44/58] ci: bump pytest from 7.4.3 to 7.4.4 in /test/requirements Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.3 to 7.4.4. - [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.4.3...7.4.4) --- 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 985fc9597..d5033424a 100644 --- a/test/requirements/python-requirements.txt +++ b/test/requirements/python-requirements.txt @@ -1,4 +1,4 @@ backoff==2.2.1 docker==7.0.0 -pytest==7.4.3 +pytest==7.4.4 requests==2.31.0 From 1433daed4da51558b43363190da7ee34b5f59531 Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:32:11 +0100 Subject: [PATCH 45/58] Install docker dependencies in nginx-proxy-tester image --- .../Dockerfile-nginx-proxy-tester | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/requirements/Dockerfile-nginx-proxy-tester b/test/requirements/Dockerfile-nginx-proxy-tester index 36984fe15..1af4a16b2 100644 --- a/test/requirements/Dockerfile-nginx-proxy-tester +++ b/test/requirements/Dockerfile-nginx-proxy-tester @@ -5,5 +5,32 @@ ENV PYTEST_RUNNING_IN_CONTAINER=1 COPY python-requirements.txt /requirements.txt RUN pip install -r /requirements.txt +# Add Docker's official GPG key +RUN apt-get update \ + && apt-get install -y \ + ca-certificates \ + curl \ + gnupg \ + && install -m 0755 -d /etc/apt/keyrings \ + && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \ + && chmod a+r /etc/apt/keyrings/docker.gpg + +# Add the Docker repository to Apt sources +RUN echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null + +# Install docker-ce-cli and docker-compose-plugin requirements for Pytest docker_compose fixture +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + docker-ce-cli \ + docker-compose-plugin \ + && apt-get clean \ + && rm -r /var/lib/apt/lists/* + +# Check if docker compose is available +RUN docker compose version + WORKDIR /test ENTRYPOINT ["pytest"] From 329b69fe76e02219be48e6d03a21671432094606 Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:33:05 +0100 Subject: [PATCH 46/58] Update test readme --- test/README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/test/README.md b/test/README.md index 056cd375b..07a29d28b 100644 --- a/test/README.md +++ b/test/README.md @@ -4,12 +4,10 @@ Nginx proxy test suite Install requirements -------------------- -You need [python 3.9](https://www.python.org/) and [pip](https://pip.pypa.io/en/stable/installing/) installed. Then run the commands: +You need [Docker Compose v2](https://docs.docker.com/compose/install/linux/), [python 3.9](https://www.python.org/) and [pip](https://pip.pypa.io/en/stable/installation/) installed. Then run the commands: pip install -r requirements/python-requirements.txt - - Prepare the nginx-proxy test image ---------------------------------- @@ -37,6 +35,16 @@ Run one single test module pytest test_nominal.py +Run the test suite from a Docker container +------------------------------------------ + +If you cannot (or don't want to) install pytest and its requirements on your computer. You can use the nginx-proxy-tester docker image to run the test suite from a Docker container. + + make test-debian + +or if you want to test the alpine flavor: + + make test-alpine Write a test module ------------------- From 63411b240743027120608abea3fb71487eb2289e Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Wed, 10 Jan 2024 17:00:47 +0100 Subject: [PATCH 47/58] build: add the openssl cli back to the alpine image --- Dockerfile.alpine | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index ffdd52cda..e4ec6d6c4 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -14,7 +14,7 @@ ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \ DOCKER_HOST=unix:///tmp/docker.sock # Install dependencies -RUN apk add --no-cache --virtual .run-deps bash +RUN apk add --no-cache --virtual .run-deps bash openssl # Configure Nginx RUN sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ From bfe9e0ac1dce62bfe049ddd5c5acc55a62e55fbc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 04:35:11 +0000 Subject: [PATCH 48/58] ci: bump peter-evans/dockerhub-description from 3 to 4 Bumps [peter-evans/dockerhub-description](https://github.com/peter-evans/dockerhub-description) from 3 to 4. - [Release notes](https://github.com/peter-evans/dockerhub-description/releases) - [Commits](https://github.com/peter-evans/dockerhub-description/compare/v3...v4) --- updated-dependencies: - dependency-name: peter-evans/dockerhub-description dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/dockerhub-description.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub-description.yml b/.github/workflows/dockerhub-description.yml index 594e132b1..4be8cc29f 100644 --- a/.github/workflows/dockerhub-description.yml +++ b/.github/workflows/dockerhub-description.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 - name: Docker Hub Description - uses: peter-evans/dockerhub-description@v3 + uses: peter-evans/dockerhub-description@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN_RWD }} From af5acae58a858f75ee638bb6053da293213dd2c3 Mon Sep 17 00:00:00 2001 From: Yan Song Liu Date: Thu, 1 Feb 2024 14:42:15 +0800 Subject: [PATCH 49/58] Add s390x support Add s390x support Signed-off-by: Yan Song Liu --- .github/workflows/build-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 1d4739323..6aeb9f540 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -88,7 +88,7 @@ jobs: build-args: | NGINX_PROXY_VERSION=${{ steps.nginx-proxy_version.outputs.VERSION }} DOCKER_GEN_VERSION=${{ steps.docker-gen_version.outputs.VERSION }} - platforms: linux/amd64,linux/arm64,linux/arm/v7 + platforms: linux/amd64,linux/arm64,linux/s390x,linux/arm/v7 sbom: true push: true provenance: mode=max From 5d10467c4264436235c06404334cfb951d00facc Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 10 Feb 2024 13:56:38 +0100 Subject: [PATCH 50/58] fix: set worker_rlimit_nofile to (worker_connections x 2) --- Dockerfile.alpine | 6 ++++-- Dockerfile.debian | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index e4ec6d6c4..d19359c0d 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -17,8 +17,10 @@ ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \ RUN apk add --no-cache --virtual .run-deps bash openssl # Configure Nginx -RUN sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ - && mkdir -p '/etc/nginx/dhparam' +RUN sed -i 's/worker_connections.*;$/worker_connections 10240;/' /etc/nginx/nginx.conf \ + && sed -i -e '/^\}$/{s//\}\nworker_rlimit_nofile 20480;/;:a' -e '$!N;$!ba' -e '}' /etc/nginx/nginx.conf \ + && mkdir -p '/etc/nginx/dhparam' \ + && mkdir -p '/etc/nginx/certs' # Install Forego + docker-gen COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego diff --git a/Dockerfile.debian b/Dockerfile.debian index 2d767fe80..1cb73d202 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -14,8 +14,10 @@ ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \ DOCKER_HOST=unix:///tmp/docker.sock # Configure Nginx -RUN sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \ - && mkdir -p '/etc/nginx/dhparam' +RUN sed -i 's/worker_connections.*;$/worker_connections 10240;/' /etc/nginx/nginx.conf \ + && sed -i -e '/^\}$/{s//\}\nworker_rlimit_nofile 20480;/;:a' -e '$!N;$!ba' -e '}' /etc/nginx/nginx.conf \ + && mkdir -p '/etc/nginx/dhparam' \ + && mkdir -p '/etc/nginx/certs' # Install Forego + docker-gen COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego From 40a347bfae4541ab92b534f2b37ea92de641f350 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 10 Feb 2024 15:23:35 +0100 Subject: [PATCH 51/58] fix: add non standard port to Host header --- nginx.tmpl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index a0be21288..f9fff01b6 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -347,6 +347,13 @@ map $http_x_forwarded_port $proxy_x_forwarded_port { '' $server_port; } +# Include the port in the Host header sent to the container if it is non-standard +map $server_port $host_port { + default :$server_port; + 80 ''; + 443 ''; +} + # If the request from the downstream client has an "Upgrade:" header (set to any # non-empty value), pass "Connection: upgrade" to the upstream (backend) server. # Otherwise, the value for the "Connection" header depends on whether the user @@ -408,7 +415,7 @@ include /etc/nginx/proxy.conf; {{- else }} # HTTP 1.1 support proxy_http_version 1.1; -proxy_set_header Host $host; +proxy_set_header Host $host$host_port; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; proxy_set_header X-Real-IP $remote_addr; From fa23c11edba63e7b4689b99521cafdc115c3cde3 Mon Sep 17 00:00:00 2001 From: jmformenti Date: Sat, 10 Feb 2024 16:24:00 +0100 Subject: [PATCH 52/58] feat: define basic auth for virtual path --- docs/README.md | 3 +++ nginx.tmpl | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 431fe6027..32d432c41 100644 --- a/docs/README.md +++ b/docs/README.md @@ -479,6 +479,9 @@ docker run -d -p 80:80 -p 443:443 \ You'll need apache2-utils on the machine where you plan to create the htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/2.2/programs/htpasswd.html) +If you want to define basic authentication for a `VIRTUAL_PATH`, you have to create a file named as /etc/ngingx/htpasswd/${VIRTUAL_HOST}_${VIRTUAL_PATH_SHA1} +(where $VIRTUAL_PATH_SHA1 is the SHA1 hash for the virtual path, you can use any SHA1 online generator to calculate it). + ### Upstream (Backend) Server HTTP Load Balancing Support > **Warning** diff --git a/nginx.tmpl b/nginx.tmpl index f9fff01b6..8b8b12e83 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -275,7 +275,10 @@ set $upstream_keepalive {{ if ne $keepalive "disabled" }}true{{ else }}false{{ end }}; {{- end }} - {{- if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }} + {{- if (exists (printf "/etc/nginx/htpasswd/%s_%s" .Host (sha1 .Path) )) }} + auth_basic "Restricted {{ .Host }}/{{ .Path }}"; + auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s_%s" .Host (sha1 .Path)) }}; + {{- else if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }} auth_basic "Restricted {{ .Host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" .Host) }}; {{- end }} From de9809a9e57bef9f2025a382ce7baa040b9cab30 Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Tue, 14 Mar 2023 12:11:33 +0100 Subject: [PATCH 53/58] Add more control over log_format config directive Introduces 3 new environmental variables: - `LOG_FORMAT` - `LOG_FORMAT_ESCAPE` - `LOG_JSON` `LOG_FORMAT` and `LOG_FORMAT_ESCAPE` default to standard values. When `LOG_JSON` is set, defaults are changed to: `{"time_local":"$time_iso8601","client_ip":"$http_x_forwarded_for","remote_addr":"$remote_addr","request":"$request","status":"$status","body_bytes_sent":"$body_bytes_sent","request_time":"$request_time","upstream_response_time":"$upstream_response_time","upstream_addr":"$upstream_addr","http_referrer":"$http_referer","http_user_agent":"$http_user_agent","request_id":"$request_id"}`and `json`. See `nginx.tmpl` and https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format for details --- nginx.tmpl | 19 ++++++++++++++++++- test/test_log_json.py | 14 ++++++++++++++ test/test_log_json.yml | 15 +++++++++++++++ test/test_log_json_format.py | 16 ++++++++++++++++ test/test_log_json_format.yml | 15 +++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 test/test_log_json.py create mode 100644 test/test_log_json.yml create mode 100644 test/test_log_json_format.py create mode 100644 test/test_log_json_format.yml diff --git a/nginx.tmpl b/nginx.tmpl index 8b8b12e83..5405e7e13 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -402,7 +402,24 @@ map $proxy_x_forwarded_proto $proxy_x_forwarded_ssl { gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; -log_format vhost '{{ or $globals.Env.LOG_FORMAT "$host $remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" \"$upstream_addr\"" }}'; + +{{- /* See https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format for details and variables + * LOG_FORMAT_ESCAPE sets the escape part of the log format + * LOG_FORMAT sets the log format + */}} +{{- $logEscape := printf "escape=%s" ( or $globals.Env.LOG_FORMAT_ESCAPE `default`) }} +{{- $logFormat := (or $globals.Env.LOG_FORMAT `$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"`) }} + +{{- if $globals.Env.LOG_JSON }} +{{- /* LOG_JSON is a shorthand + * that sets logging defaults to JSON format + */}} +# JSON Logging enabled (via LOG_JSON env variable) +{{- $logEscape = printf "escape=%s" ( or $globals.Env.LOG_FORMAT_ESCAPE `json`) }} +{{- $logFormat = (or $globals.Env.LOG_FORMAT `{"time_local":"$time_iso8601","client_ip":"$http_x_forwarded_for","remote_addr":"$remote_addr","request":"$request","status":"$status","body_bytes_sent":"$body_bytes_sent","request_time":"$request_time","upstream_response_time":"$upstream_response_time","upstream_addr":"$upstream_addr","http_referrer":"$http_referer","http_user_agent":"$http_user_agent","request_id":"$request_id"}`) }} +{{- end }} + +log_format vhost {{ $logEscape }} '{{ or $globals.Env.LOG_FORMAT $logFormat }}'; access_log off; diff --git a/test/test_log_json.py b/test/test_log_json.py new file mode 100644 index 000000000..1a04b228c --- /dev/null +++ b/test/test_log_json.py @@ -0,0 +1,14 @@ +import pytest + +def test_log_json(docker_compose, nginxproxy): + log_conf = [line for line in nginxproxy.get_conf().decode('ASCII').splitlines() if "log_format vhost escape=" in line] + assert "{\"time_local\":\"$time_iso8601\"," in log_conf[0] + + r = nginxproxy.get("http://nginx-proxy.test/port") + assert r.status_code == 200 + assert r.text == "answer from port 81\n" + sut_container = docker_compose.containers.get("sut") + docker_logs = sut_container.logs(stdout=True, stderr=True, stream=False, follow=False) + docker_logs = docker_logs.decode("utf-8").splitlines() + docker_logs = [line for line in docker_logs if "{\"time_local\":" in line] + assert "GET /port" in docker_logs[0] diff --git a/test/test_log_json.yml b/test/test_log_json.yml new file mode 100644 index 000000000..774019143 --- /dev/null +++ b/test/test_log_json.yml @@ -0,0 +1,15 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: nginx-proxy.test + +sut: + container_name: sut + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + LOG_JSON: 1 diff --git a/test/test_log_json_format.py b/test/test_log_json_format.py new file mode 100644 index 000000000..56cfdeae4 --- /dev/null +++ b/test/test_log_json_format.py @@ -0,0 +1,16 @@ +import pytest + +def test_log_json_format(docker_compose, nginxproxy): + log_conf = [line for line in nginxproxy.get_conf().decode('ASCII').splitlines() if "log_format vhost escape=" in line] + assert "{\"time_local\":\"$time_iso8601\"," in log_conf[0] + + r = nginxproxy.get("http://nginx-proxy.test/port") + assert r.status_code == 200 + assert r.text == "answer from port 81\n" + sut_container = docker_compose.containers.get("sut") + docker_logs = sut_container.logs(stdout=True, stderr=True, stream=False, follow=False) + docker_logs = docker_logs.decode("utf-8").splitlines() + docker_logs = [line for line in docker_logs if "{\"time_local\":" in line] + assert "GET /port" in docker_logs[0] + + diff --git a/test/test_log_json_format.yml b/test/test_log_json_format.yml new file mode 100644 index 000000000..caf20a795 --- /dev/null +++ b/test/test_log_json_format.yml @@ -0,0 +1,15 @@ +web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: nginx-proxy.test + +sut: + container_name: sut + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + LOG_FORMAT: '{"time_local":"$$time_iso8601","remote_addr":"$$remote_addr","request":"$$request","upstream_addr":"$$upstream_addr"}' From 8aefce916f2b5c6dcf8f6130fe73348ee49306aa Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 10 Feb 2024 18:02:42 +0100 Subject: [PATCH 54/58] tests: fix the json log test compose files --- test/test_log_json.yml | 31 +++++++++++++++++-------------- test/test_log_json_format.yml | 31 +++++++++++++++++-------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/test/test_log_json.yml b/test/test_log_json.yml index 774019143..2e6fefdba 100644 --- a/test/test_log_json.yml +++ b/test/test_log_json.yml @@ -1,15 +1,18 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: nginx-proxy.test +version: "2" -sut: - container_name: sut - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - environment: - LOG_JSON: 1 +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: nginx-proxy.test + + sut: + container_name: sut + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + LOG_JSON: 1 diff --git a/test/test_log_json_format.yml b/test/test_log_json_format.yml index caf20a795..5e01e924f 100644 --- a/test/test_log_json_format.yml +++ b/test/test_log_json_format.yml @@ -1,15 +1,18 @@ -web1: - image: web - expose: - - "81" - environment: - WEB_PORTS: 81 - VIRTUAL_HOST: nginx-proxy.test +version: "2" -sut: - container_name: sut - image: nginxproxy/nginx-proxy:test - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - environment: - LOG_FORMAT: '{"time_local":"$$time_iso8601","remote_addr":"$$remote_addr","request":"$$request","upstream_addr":"$$upstream_addr"}' +services: + web1: + image: web + expose: + - "81" + environment: + WEB_PORTS: 81 + VIRTUAL_HOST: nginx-proxy.test + + sut: + container_name: sut + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + LOG_FORMAT: '{"time_local":"$$time_iso8601","remote_addr":"$$remote_addr","request":"$$request","upstream_addr":"$$upstream_addr"}' From 76778cebb17d24629a0aea3c13565d111f64d939 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 10 Feb 2024 17:54:14 +0100 Subject: [PATCH 55/58] refactor: parse LOG_JSON as boolean + avoid unnecessary backticks --- nginx.tmpl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 5405e7e13..c72c1c7a4 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -407,16 +407,16 @@ gzip_types text/plain text/css application/javascript application/json applicati * LOG_FORMAT_ESCAPE sets the escape part of the log format * LOG_FORMAT sets the log format */}} -{{- $logEscape := printf "escape=%s" ( or $globals.Env.LOG_FORMAT_ESCAPE `default`) }} -{{- $logFormat := (or $globals.Env.LOG_FORMAT `$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"`) }} +{{- $logEscape := printf "escape=%s" (or $globals.Env.LOG_FORMAT_ESCAPE "default") }} +{{- $logFormat := or $globals.Env.LOG_FORMAT `$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"` }} -{{- if $globals.Env.LOG_JSON }} -{{- /* LOG_JSON is a shorthand - * that sets logging defaults to JSON format - */}} +{{- if parseBool (or $globals.Env.LOG_JSON "false") }} + {{- /* LOG_JSON is a shorthand + * that sets logging defaults to JSON format + */}} # JSON Logging enabled (via LOG_JSON env variable) -{{- $logEscape = printf "escape=%s" ( or $globals.Env.LOG_FORMAT_ESCAPE `json`) }} -{{- $logFormat = (or $globals.Env.LOG_FORMAT `{"time_local":"$time_iso8601","client_ip":"$http_x_forwarded_for","remote_addr":"$remote_addr","request":"$request","status":"$status","body_bytes_sent":"$body_bytes_sent","request_time":"$request_time","upstream_response_time":"$upstream_response_time","upstream_addr":"$upstream_addr","http_referrer":"$http_referer","http_user_agent":"$http_user_agent","request_id":"$request_id"}`) }} + {{- $logEscape = printf "escape=%s" (or $globals.Env.LOG_FORMAT_ESCAPE "json") }} + {{- $logFormat = or $globals.Env.LOG_FORMAT `{"time_local":"$time_iso8601","client_ip":"$http_x_forwarded_for","remote_addr":"$remote_addr","request":"$request","status":"$status","body_bytes_sent":"$body_bytes_sent","request_time":"$request_time","upstream_response_time":"$upstream_response_time","upstream_addr":"$upstream_addr","http_referrer":"$http_referer","http_user_agent":"$http_user_agent","request_id":"$request_id"}` }} {{- end }} log_format vhost {{ $logEscape }} '{{ or $globals.Env.LOG_FORMAT $logFormat }}'; From 62f55b4428a1133e5f44a75dde310271fef28c60 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 10 Feb 2024 19:03:13 +0100 Subject: [PATCH 56/58] docs: add logging documentation --- docs/README.md | 65 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/docs/README.md b/docs/README.md index 32d432c41..e381b7f19 100644 --- a/docs/README.md +++ b/docs/README.md @@ -181,12 +181,61 @@ If you would like to connect to FastCGI backend, set `VIRTUAL_PROTO=fastcgi` on If you use fastcgi,you can set `VIRTUAL_ROOT=xxx` for your root directory -### Custom log format +### Logging -If you want to use a custom log format, you can set `LOG_FORMAT=xxx` on the proxy container. +The default nginx access log format is + +``` +$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr" +``` + +#### Custom log format + +If you want to use a custom access log format, you can set `LOG_FORMAT=xxx` on the proxy container. With docker compose take care to escape the `$` character with `$$` to avoid variable interpolation. Example: `$remote_addr` becomes `$$remote_addr`. +#### JSON log format + +If you want access logs in JSON format, you can set `LOG_JSON=true`. This will correctly set the escape character to `json` and the log format to : + +```json +{ + "time_local": "$time_iso8601", + "client_ip": "$http_x_forwarded_for", + "remote_addr": "$remote_addr", + "request": "$request", + "status": "$status", + "body_bytes_sent": "$body_bytes_sent", + "request_time": "$request_time", + "upstream_response_time": "$upstream_response_time", + "upstream_addr": "$upstream_addr", + "http_referrer": "$http_referer", + "http_user_agent": "$http_user_agent", + "request_id": "$request_id" +} +``` + +#### Log format escaping + +If you want to manually set nginx `log_format`'s `escape`, set the `LOG_FORMAT_ESCAPE` variable to [a value supported by nginx](https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format). + +#### Disable access logs + +To disable nginx access logs entirely, set the `DISABLE_ACCESS_LOGS` environment variable to any value. + +#### Disabling colors in the container log output + +To remove colors from the container log output, set the [`NO_COLOR` environment variable to any value other than an empty string](https://no-color.org/) on the nginx-proxy container. + +```console +docker run --detach \ + --publish 80:80 \ + --env NO_COLOR=1 \ + --volume /var/run/docker.sock:/tmp/docker.sock:ro \ + nginxproxy/nginx-proxy +``` + ### Default Host To set the default host for nginx use the env var `DEFAULT_HOST=foo.bar.com` for example @@ -679,18 +728,6 @@ By default the nginx configuration `upstream` blocks will use this block's corre Please note that using regular expressions in `VIRTUAL_HOST` will always result in a corresponding `upstream` block with an SHA1 name. -### Disabling colors in the log output - -To remove colors from the log output, set the [`NO_COLOR` environment variable to any value other than an empty string](https://no-color.org/) on the nginx-proxy container. - -```console -docker run --detach \ - --publish 80:80 \ - --env NO_COLOR=1 \ - --volume /var/run/docker.sock:/tmp/docker.sock:ro \ - nginxproxy/nginx-proxy -``` - ### Troubleshooting If you can't access your `VIRTUAL_HOST`, inspect the generated nginx configuration: From 25883ac05fd3ba2ca0efcad2d45200ac62fb5f6b Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 10 Feb 2024 19:04:56 +0100 Subject: [PATCH 57/58] style: remove extra blank lines --- test/test_log_json_format.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_log_json_format.py b/test/test_log_json_format.py index 56cfdeae4..2d158cb7c 100644 --- a/test/test_log_json_format.py +++ b/test/test_log_json_format.py @@ -12,5 +12,3 @@ def test_log_json_format(docker_compose, nginxproxy): docker_logs = docker_logs.decode("utf-8").splitlines() docker_logs = [line for line in docker_logs if "{\"time_local\":" in line] assert "GET /port" in docker_logs[0] - - From 3a193827025aeaa4d8c77e79003522b11eca5adf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:16:49 +0000 Subject: [PATCH 58/58] build: bump nginxproxy/docker-gen from 0.11.1-debian to 0.11.2-debian Bumps nginxproxy/docker-gen from 0.11.1-debian to 0.11.2-debian. --- updated-dependencies: - dependency-name: nginxproxy/docker-gen dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile.alpine | 2 +- Dockerfile.debian | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index d19359c0d..1a1c8bf7f 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,4 +1,4 @@ -FROM nginxproxy/docker-gen:0.11.1 AS docker-gen +FROM nginxproxy/docker-gen:0.11.2 AS docker-gen FROM nginxproxy/forego:0.18.1 AS forego diff --git a/Dockerfile.debian b/Dockerfile.debian index 1cb73d202..a8c26bc30 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -1,4 +1,4 @@ -FROM nginxproxy/docker-gen:0.11.1-debian AS docker-gen +FROM nginxproxy/docker-gen:0.11.2-debian AS docker-gen FROM nginxproxy/forego:0.18.1-debian AS forego