mirror of
https://github.com/thib8956/nginx-proxy
synced 2025-02-24 01:38:15 +00:00
Merge pull request #2525 from nginx-proxy/debug-endpoint
feat: nginx-proxy debug endpoint
This commit is contained in:
commit
031a2b16bb
@ -982,7 +982,7 @@ docker exec <nginx-proxy-instance> nginx -T
|
|||||||
|
|
||||||
Pay attention to the `upstream` definition blocks, which should look like this:
|
Pay attention to the `upstream` definition blocks, which should look like this:
|
||||||
|
|
||||||
```Nginx
|
```nginx
|
||||||
# foo.example.com
|
# foo.example.com
|
||||||
upstream foo.example.com {
|
upstream foo.example.com {
|
||||||
## Can be connected with "my_network" network
|
## Can be connected with "my_network" network
|
||||||
@ -1002,6 +1002,101 @@ The effective `Port` is retrieved by order of precedence:
|
|||||||
1. From the container's exposed port if there is only one
|
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
|
1. From the default port 80 when none of the above methods apply
|
||||||
|
|
||||||
|
### Debug endpoint
|
||||||
|
|
||||||
|
The debug endpoint can be enabled:
|
||||||
|
- globally by setting the `DEBUG_ENDPOINT` environment variable to `true` on the nginx-proxy container.
|
||||||
|
- per container by setting the `com.github.nginx-proxy.nginx-proxy.debug-endpoint` label to `true` on a proxied container.
|
||||||
|
|
||||||
|
Enabling it will expose the endpoint at `<your.domain.tld>/nginx-proxy-debug`.
|
||||||
|
|
||||||
|
Querying the debug endpoint will show the global config, along with the virtual host and per path configs in JSON format.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
nginx-proxy:
|
||||||
|
image: nginxproxy/nginx-proxy
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
environment:
|
||||||
|
DEBUG_ENDPOINT: "true"
|
||||||
|
|
||||||
|
test:
|
||||||
|
image: nginx
|
||||||
|
environment:
|
||||||
|
VIRTUAL_HOST: test.nginx-proxy.tld
|
||||||
|
```
|
||||||
|
|
||||||
|
(on the CLI, using [`jq`](https://jqlang.github.io/jq/) to format the output of `curl` is recommended)
|
||||||
|
|
||||||
|
```console
|
||||||
|
curl -s -H "Host: test.nginx-proxy.tld" localhost/nginx-proxy-debug | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"global": {
|
||||||
|
"default_cert_ok": false,
|
||||||
|
"default_root_response": "404",
|
||||||
|
"enable_access_log": true,
|
||||||
|
"enable_debug_endpoint": "true",
|
||||||
|
"enable_ipv6": false,
|
||||||
|
"external_http_port": "80",
|
||||||
|
"external_https_port": "443",
|
||||||
|
"nginx_proxy_version": "local",
|
||||||
|
"sha1_upstream_name": false,
|
||||||
|
"ssl_policy": "Mozilla-Intermediate",
|
||||||
|
"trust_downstream_proxy": true
|
||||||
|
},
|
||||||
|
"hostname": "test.nginx-proxy.tld",
|
||||||
|
"request": {
|
||||||
|
"host": "test.nginx-proxy.tld",
|
||||||
|
"http2": "",
|
||||||
|
"http3": "",
|
||||||
|
"https": "",
|
||||||
|
"ssl_cipher": "",
|
||||||
|
"ssl_protocol": ""
|
||||||
|
},
|
||||||
|
"vhost": {
|
||||||
|
"acme_http_challenge_enabled": true,
|
||||||
|
"acme_http_challenge_legacy": false,
|
||||||
|
"cert": "",
|
||||||
|
"cert_ok": false,
|
||||||
|
"default": false,
|
||||||
|
"enable_debug_endpoint": true,
|
||||||
|
"hsts": "max-age=31536000",
|
||||||
|
"http2_enabled": true,
|
||||||
|
"http3_enabled": false,
|
||||||
|
"https_method": "noredirect",
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"dest": "",
|
||||||
|
"keepalive": "disabled",
|
||||||
|
"network_tag": "external",
|
||||||
|
"ports": {
|
||||||
|
"legacy": [
|
||||||
|
{
|
||||||
|
"Name": "wip-test-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"proto": "http",
|
||||||
|
"upstream": "test.nginx-proxy.tld"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"server_tokens": "",
|
||||||
|
"ssl_policy": "",
|
||||||
|
"upstream_name": "test.nginx-proxy.tld",
|
||||||
|
"vhost_root": "/var/www/public"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:warning: please be aware that the debug endpoint work by rendering the JSON response straight to the nginx configuration in plaintext. nginx has an upper limit on the size of the configuration files it can parse, so only activate it when needed, and preferably on a per container basis if your setup has a large number of virtual hosts.
|
||||||
|
|
||||||
|
|
||||||
⬆️ [back to table of contents](#table-of-contents)
|
⬆️ [back to table of contents](#table-of-contents)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
161
nginx.tmpl
161
nginx.tmpl
@ -11,15 +11,21 @@
|
|||||||
{{- $_ := set $globals "Env" $.Env }}
|
{{- $_ := set $globals "Env" $.Env }}
|
||||||
{{- $_ := set $globals "Docker" $.Docker }}
|
{{- $_ := set $globals "Docker" $.Docker }}
|
||||||
{{- $_ := set $globals "CurrentContainer" (where $globals.containers "ID" $globals.Docker.CurrentContainerID | first) }}
|
{{- $_ := set $globals "CurrentContainer" (where $globals.containers "ID" $globals.Docker.CurrentContainerID | first) }}
|
||||||
{{- $_ := set $globals "default_cert_ok" (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
|
|
||||||
{{- $_ := set $globals "external_http_port" (coalesce $globals.Env.HTTP_PORT "80") }}
|
{{- $config := dict }}
|
||||||
{{- $_ := set $globals "external_https_port" (coalesce $globals.Env.HTTPS_PORT "443") }}
|
{{- $_ := set $config "nginx_proxy_version" $.Env.NGINX_PROXY_VERSION }}
|
||||||
{{- $_ := set $globals "sha1_upstream_name" (parseBool (coalesce $globals.Env.SHA1_UPSTREAM_NAME "false")) }}
|
{{- $_ := set $config "default_cert_ok" (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
|
||||||
{{- $_ := set $globals "default_root_response" (coalesce $globals.Env.DEFAULT_ROOT "404") }}
|
{{- $_ := set $config "external_http_port" (coalesce $globals.Env.HTTP_PORT "80") }}
|
||||||
{{- $_ := set $globals "trust_downstream_proxy" (parseBool (coalesce $globals.Env.TRUST_DOWNSTREAM_PROXY "true")) }}
|
{{- $_ := set $config "external_https_port" (coalesce $globals.Env.HTTPS_PORT "443") }}
|
||||||
{{- $_ := set $globals "access_log" (or (and (not $globals.Env.DISABLE_ACCESS_LOGS) "access_log /var/log/nginx/access.log vhost;") "") }}
|
{{- $_ := set $config "sha1_upstream_name" (parseBool (coalesce $globals.Env.SHA1_UPSTREAM_NAME "false")) }}
|
||||||
{{- $_ := set $globals "enable_ipv6" (parseBool (coalesce $globals.Env.ENABLE_IPV6 "false")) }}
|
{{- $_ := set $config "default_root_response" (coalesce $globals.Env.DEFAULT_ROOT "404") }}
|
||||||
{{- $_ := set $globals "ssl_policy" (or ($globals.Env.SSL_POLICY) "Mozilla-Intermediate") }}
|
{{- $_ := set $config "trust_downstream_proxy" (parseBool (coalesce $globals.Env.TRUST_DOWNSTREAM_PROXY "true")) }}
|
||||||
|
{{- $_ := set $config "enable_access_log" ($globals.Env.DISABLE_ACCESS_LOGS | default "false" | parseBool | not) }}
|
||||||
|
{{- $_ := set $config "enable_ipv6" (parseBool (coalesce $globals.Env.ENABLE_IPV6 "false")) }}
|
||||||
|
{{- $_ := set $config "ssl_policy" (or ($globals.Env.SSL_POLICY) "Mozilla-Intermediate") }}
|
||||||
|
{{- $_ := set $config "enable_debug_endpoint" ($globals.Env.DEBUG_ENDPOINT | default "false") }}
|
||||||
|
{{- $_ := set $globals "config" $config }}
|
||||||
|
|
||||||
{{- $_ := set $globals "vhosts" (dict) }}
|
{{- $_ := set $globals "vhosts" (dict) }}
|
||||||
{{- $_ := set $globals "networks" (dict) }}
|
{{- $_ := set $globals "networks" (dict) }}
|
||||||
# Networks available to the container running docker-gen (which are assumed to
|
# Networks available to the container running docker-gen (which are assumed to
|
||||||
@ -344,22 +350,75 @@ upstream {{ $vpath.upstream }} {
|
|||||||
}
|
}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- /* debug "endpoint" location template */}}
|
||||||
|
{{- define "debug_location" }}
|
||||||
|
{{- $debug_paths := dict }}
|
||||||
|
{{- range $path, $vpath := .VHost.paths }}
|
||||||
|
{{- $tmp_port := dict }}
|
||||||
|
{{- range $port, $containers := $vpath.ports }}
|
||||||
|
{{- $tmp_containers := list }}
|
||||||
|
{{- range $container := $containers }}
|
||||||
|
{{- $tmp_containers = dict "Name" $container.Name | append $tmp_containers }}
|
||||||
|
{{- end }}
|
||||||
|
{{- $_ := dict $port $tmp_containers | set $tmp_port "ports" }}
|
||||||
|
{{- $tmp_port = deepCopy $vpath | merge $tmp_port }}
|
||||||
|
{{- end }}
|
||||||
|
{{- $_ := set $debug_paths $path $tmp_port }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- $debug_vhost := deepCopy .VHost }}
|
||||||
|
{{- $_ := set $debug_vhost "paths" $debug_paths }}
|
||||||
|
|
||||||
|
{{- $debug_response := dict
|
||||||
|
"global" .GlobalConfig
|
||||||
|
"hostname" .Hostname
|
||||||
|
"request" (dict
|
||||||
|
"host" "$host"
|
||||||
|
"https" "$https"
|
||||||
|
"http2" "$http2"
|
||||||
|
"http3" "$http3"
|
||||||
|
"ssl_cipher" "$ssl_cipher"
|
||||||
|
"ssl_protocol" "$ssl_protocol"
|
||||||
|
)
|
||||||
|
"vhost" $debug_vhost
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{- /*
|
||||||
|
* The maximum line length in an nginx config is 4096 characters.
|
||||||
|
* If we're nearing this limit (with headroom for the rest
|
||||||
|
* of the directive), strip vhost.paths from the response.
|
||||||
|
*/}}
|
||||||
|
{{- if gt (toJson $debug_response | len) 4000 }}
|
||||||
|
{{- $_ := unset $debug_vhost "paths" }}
|
||||||
|
{{- $_ := set $debug_response "warning" "Virtual paths configuration for this hostname is too large and has been stripped from response." }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
location /nginx-proxy-debug {
|
||||||
|
default_type application/json;
|
||||||
|
return 200 '{{ toJson $debug_response }}';
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- define "access_log" }}
|
||||||
|
{{- when .Enable "access_log /var/log/nginx/access.log vhost;" "" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
|
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
|
||||||
# scheme used to connect to this server
|
# scheme used to connect to this server
|
||||||
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
|
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
|
||||||
default {{ if $globals.trust_downstream_proxy }}$http_x_forwarded_proto{{ else }}$scheme{{ end }};
|
default {{ if $globals.config.trust_downstream_proxy }}$http_x_forwarded_proto{{ else }}$scheme{{ end }};
|
||||||
'' $scheme;
|
'' $scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
map $http_x_forwarded_host $proxy_x_forwarded_host {
|
map $http_x_forwarded_host $proxy_x_forwarded_host {
|
||||||
default {{ if $globals.trust_downstream_proxy }}$http_x_forwarded_host{{ else }}$host{{ end }};
|
default {{ if $globals.config.trust_downstream_proxy }}$http_x_forwarded_host{{ else }}$host{{ end }};
|
||||||
'' $host;
|
'' $host;
|
||||||
}
|
}
|
||||||
|
|
||||||
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
|
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
|
||||||
# server port the client connected to
|
# server port the client connected to
|
||||||
map $http_x_forwarded_port $proxy_x_forwarded_port {
|
map $http_x_forwarded_port $proxy_x_forwarded_port {
|
||||||
default {{ if $globals.trust_downstream_proxy }}$http_x_forwarded_port{{ else }}$server_port{{ end }};
|
default {{ if $globals.config.trust_downstream_proxy }}$http_x_forwarded_port{{ else }}$server_port{{ end }};
|
||||||
'' $server_port;
|
'' $server_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +499,7 @@ access_log off;
|
|||||||
* if at least one vhost use a TLSv1 or TLSv1.1 policy
|
* if at least one vhost use a TLSv1 or TLSv1.1 policy
|
||||||
* so TLSv1 and TLSv1.1 can be enabled on those vhosts
|
* so TLSv1 and TLSv1.1 can be enabled on those vhosts
|
||||||
*/}}
|
*/}}
|
||||||
{{- $httpContextSslPolicy := $globals.ssl_policy }}
|
{{- $httpContextSslPolicy := $globals.config.ssl_policy }}
|
||||||
{{- $inUseSslPolicies := groupByKeys $globals.containers "Env.SSL_POLICY" }}
|
{{- $inUseSslPolicies := groupByKeys $globals.containers "Env.SSL_POLICY" }}
|
||||||
{{- range $tls1Policy := list "AWS-TLS13-1-1-2021-06" "AWS-TLS13-1-0-2021-06" "AWS-FS-1-1-2019-08" "AWS-FS-2018-06" "AWS-TLS-1-1-2017-01" "AWS-2016-08" "AWS-2015-05" "AWS-2015-03" "AWS-2015-02" "Mozilla-Old" }}
|
{{- range $tls1Policy := list "AWS-TLS13-1-1-2021-06" "AWS-TLS13-1-0-2021-06" "AWS-FS-1-1-2019-08" "AWS-FS-2018-06" "AWS-TLS-1-1-2017-01" "AWS-2016-08" "AWS-2015-05" "AWS-2015-03" "AWS-2015-02" "Mozilla-Old" }}
|
||||||
{{- if has $tls1Policy $inUseSslPolicies }}
|
{{- if has $tls1Policy $inUseSslPolicies }}
|
||||||
@ -518,7 +577,7 @@ proxy_set_header Proxy "";
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
{{- $_ := set $vhost_data "paths" $paths }}
|
{{- $_ := set $vhost_data "paths" $paths }}
|
||||||
{{- $is_regexp := hasPrefix "~" $hostname }}
|
{{- $is_regexp := hasPrefix "~" $hostname }}
|
||||||
{{- $_ := set $vhost_data "upstream_name" (when (or $is_regexp $globals.sha1_upstream_name) (sha1 $hostname) $hostname) }}
|
{{- $_ := set $vhost_data "upstream_name" (when (or $is_regexp $globals.config.sha1_upstream_name) (sha1 $hostname) $hostname) }}
|
||||||
{{- $_ := set $globals.vhosts $hostname $vhost_data }}
|
{{- $_ := set $globals.vhosts $hostname $vhost_data }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@ -564,7 +623,7 @@ proxy_set_header Proxy "";
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
{{- $_ := set $vhost_data "paths" $paths }}
|
{{- $_ := set $vhost_data "paths" $paths }}
|
||||||
{{- $is_regexp := hasPrefix "~" $hostname }}
|
{{- $is_regexp := hasPrefix "~" $hostname }}
|
||||||
{{- $_ := set $vhost_data "upstream_name" (when (or $is_regexp $globals.sha1_upstream_name) (sha1 $hostname) $hostname) }}
|
{{- $_ := set $vhost_data "upstream_name" (when (or $is_regexp $globals.config.sha1_upstream_name) (sha1 $hostname) $hostname) }}
|
||||||
{{- $_ := set $globals.vhosts $hostname $vhost_data }}
|
{{- $_ := set $globals.vhosts $hostname $vhost_data }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
@ -610,6 +669,7 @@ proxy_set_header Proxy "";
|
|||||||
{{- $cert := or $certName $vhostCert }}
|
{{- $cert := or $certName $vhostCert }}
|
||||||
{{- $cert_ok := and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert)) }}
|
{{- $cert_ok := and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert)) }}
|
||||||
|
|
||||||
|
{{- $enable_debug_endpoint := coalesce (groupByLabel $vhost_containers "com.github.nginx-proxy.nginx-proxy.debug-endpoint" | keys | first) $globals.config.enable_debug_endpoint | parseBool }}
|
||||||
{{- $default := eq $globals.Env.DEFAULT_HOST $hostname }}
|
{{- $default := eq $globals.Env.DEFAULT_HOST $hostname }}
|
||||||
{{- $https_method := or (first (groupByKeys $vhost_containers "Env.HTTPS_METHOD")) $globals.Env.HTTPS_METHOD "redirect" }}
|
{{- $https_method := or (first (groupByKeys $vhost_containers "Env.HTTPS_METHOD")) $globals.Env.HTTPS_METHOD "redirect" }}
|
||||||
{{- $enable_http_on_missing_cert := parseBool (or (first (groupByKeys $vhost_containers "Env.ENABLE_HTTP_ON_MISSING_CERT")) $globals.Env.ENABLE_HTTP_ON_MISSING_CERT "true") }}
|
{{- $enable_http_on_missing_cert := parseBool (or (first (groupByKeys $vhost_containers "Env.ENABLE_HTTP_ON_MISSING_CERT")) $globals.Env.ENABLE_HTTP_ON_MISSING_CERT "true") }}
|
||||||
@ -641,6 +701,7 @@ proxy_set_header Proxy "";
|
|||||||
{{- $vhost_data = merge $vhost_data (dict
|
{{- $vhost_data = merge $vhost_data (dict
|
||||||
"cert" $cert
|
"cert" $cert
|
||||||
"cert_ok" $cert_ok
|
"cert_ok" $cert_ok
|
||||||
|
"enable_debug_endpoint" $enable_debug_endpoint
|
||||||
"default" $default
|
"default" $default
|
||||||
"hsts" $hsts
|
"hsts" $hsts
|
||||||
"https_method" $https_method
|
"https_method" $https_method
|
||||||
@ -700,30 +761,30 @@ proxy_set_header Proxy "";
|
|||||||
server {
|
server {
|
||||||
server_name _; # This is just an invalid value which will never trigger on a real hostname.
|
server_name _; # This is just an invalid value which will never trigger on a real hostname.
|
||||||
server_tokens off;
|
server_tokens off;
|
||||||
{{ $globals.access_log }}
|
{{ template "access_log" (dict "Enable" $globals.config.enable_access_log) }}
|
||||||
http2 on;
|
http2 on;
|
||||||
{{- if $fallback_http }}
|
{{- if $fallback_http }}
|
||||||
listen {{ $globals.external_http_port }}; {{- /* Do not add `default_server` (see comment above). */}}
|
listen {{ $globals.config.external_http_port }}; {{- /* Do not add `default_server` (see comment above). */}}
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.config.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_http_port }}; {{- /* Do not add `default_server` (see comment above). */}}
|
listen [::]:{{ $globals.config.external_http_port }}; {{- /* Do not add `default_server` (see comment above). */}}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if $fallback_https }}
|
{{- if $fallback_https }}
|
||||||
listen {{ $globals.external_https_port }} ssl; {{- /* Do not add `default_server` (see comment above). */}}
|
listen {{ $globals.config.external_https_port }} ssl; {{- /* Do not add `default_server` (see comment above). */}}
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.config.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_https_port }} ssl; {{- /* Do not add `default_server` (see comment above). */}}
|
listen [::]:{{ $globals.config.external_https_port }} ssl; {{- /* Do not add `default_server` (see comment above). */}}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if $http3_enabled }}
|
{{- if $http3_enabled }}
|
||||||
http3 on;
|
http3 on;
|
||||||
listen {{ $globals.external_https_port }} quic reuseport; {{- /* Do not add `default_server` (see comment above). */}}
|
listen {{ $globals.config.external_https_port }} quic reuseport; {{- /* Do not add `default_server` (see comment above). */}}
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.config.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_https_port }} quic reuseport; {{- /* Do not add `default_server` (see comment above). */}}
|
listen [::]:{{ $globals.config.external_https_port }} quic reuseport; {{- /* Do not add `default_server` (see comment above). */}}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
ssl_session_cache shared:SSL:50m;
|
ssl_session_cache shared:SSL:50m;
|
||||||
ssl_session_tickets off;
|
ssl_session_tickets off;
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if $globals.default_cert_ok }}
|
{{- if $globals.config.default_cert_ok }}
|
||||||
ssl_certificate /etc/nginx/certs/default.crt;
|
ssl_certificate /etc/nginx/certs/default.crt;
|
||||||
ssl_certificate_key /etc/nginx/certs/default.key;
|
ssl_certificate_key /etc/nginx/certs/default.key;
|
||||||
{{- else }}
|
{{- else }}
|
||||||
@ -759,10 +820,10 @@ server {
|
|||||||
{{- if $vhost.server_tokens }}
|
{{- if $vhost.server_tokens }}
|
||||||
server_tokens {{ $vhost.server_tokens }};
|
server_tokens {{ $vhost.server_tokens }};
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{ $globals.access_log }}
|
{{ template "access_log" (dict "Enable" $globals.config.enable_access_log) }}
|
||||||
listen {{ $globals.external_http_port }} {{ $default_server }};
|
listen {{ $globals.config.external_http_port }} {{ $default_server }};
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.config.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_http_port }} {{ $default_server }};
|
listen [::]:{{ $globals.config.external_http_port }} {{ $default_server }};
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- if (or $vhost.acme_http_challenge_legacy $vhost.acme_http_challenge_enabled) }}
|
{{- if (or $vhost.acme_http_challenge_legacy $vhost.acme_http_challenge_enabled) }}
|
||||||
@ -776,12 +837,16 @@ server {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if $vhost.enable_debug_endpoint }}
|
||||||
|
{{ template "debug_location" (dict "GlobalConfig" $globals.config "Hostname" $hostname "VHost" $vhost) }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
{{- if eq $globals.external_https_port "443" }}
|
{{- if eq $globals.config.external_https_port "443" }}
|
||||||
return 301 https://$host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
{{- else }}
|
{{- else }}
|
||||||
return 301 https://$host:{{ $globals.external_https_port }}$request_uri;
|
return 301 https://$host:{{ $globals.config.external_https_port }}$request_uri;
|
||||||
{{- end }}
|
{{- end }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -809,14 +874,14 @@ server {
|
|||||||
{{- if $vhost.server_tokens }}
|
{{- if $vhost.server_tokens }}
|
||||||
server_tokens {{ $vhost.server_tokens }};
|
server_tokens {{ $vhost.server_tokens }};
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{ $globals.access_log }}
|
{{ template "access_log" (dict "Enable" $globals.config.enable_access_log) }}
|
||||||
{{- if $vhost.http2_enabled }}
|
{{- if $vhost.http2_enabled }}
|
||||||
http2 on;
|
http2 on;
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if or (eq $vhost.https_method "nohttps") (eq $vhost.https_method "noredirect") }}
|
{{- if or (eq $vhost.https_method "nohttps") (eq $vhost.https_method "noredirect") }}
|
||||||
listen {{ $globals.external_http_port }} {{ $default_server }};
|
listen {{ $globals.config.external_http_port }} {{ $default_server }};
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.config.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_http_port }} {{ $default_server }};
|
listen [::]:{{ $globals.config.external_http_port }} {{ $default_server }};
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- if (and (eq $vhost.https_method "noredirect") $vhost.acme_http_challenge_enabled) }}
|
{{- if (and (eq $vhost.https_method "noredirect") $vhost.acme_http_challenge_enabled) }}
|
||||||
@ -830,17 +895,17 @@ server {
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if ne $vhost.https_method "nohttps" }}
|
{{- if ne $vhost.https_method "nohttps" }}
|
||||||
listen {{ $globals.external_https_port }} ssl {{ $default_server }};
|
listen {{ $globals.config.external_https_port }} ssl {{ $default_server }};
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.config.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_https_port }} ssl {{ $default_server }};
|
listen [::]:{{ $globals.config.external_https_port }} ssl {{ $default_server }};
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- if $vhost.http3_enabled }}
|
{{- if $vhost.http3_enabled }}
|
||||||
http3 on;
|
http3 on;
|
||||||
add_header alt-svc 'h3=":{{ $globals.external_https_port }}"; ma=86400;';
|
add_header alt-svc 'h3=":{{ $globals.config.external_https_port }}"; ma=86400;';
|
||||||
listen {{ $globals.external_https_port }} quic {{ $default_server }};
|
listen {{ $globals.config.external_https_port }} quic {{ $default_server }};
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.config.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_https_port }} quic {{ $default_server }};
|
listen [::]:{{ $globals.config.external_https_port }} quic {{ $default_server }};
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
@ -871,7 +936,7 @@ server {
|
|||||||
}
|
}
|
||||||
add_header Strict-Transport-Security $sts_header always;
|
add_header Strict-Transport-Security $sts_header always;
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- else if $globals.default_cert_ok }}
|
{{- else if $globals.config.default_cert_ok }}
|
||||||
# No certificate found for this vhost, so use the default certificate and
|
# No certificate found for this vhost, so use the default certificate and
|
||||||
# return an error code if the user connects via https.
|
# return an error code if the user connects via https.
|
||||||
ssl_certificate /etc/nginx/certs/default.crt;
|
ssl_certificate /etc/nginx/certs/default.crt;
|
||||||
@ -893,6 +958,10 @@ server {
|
|||||||
include /etc/nginx/vhost.d/default;
|
include /etc/nginx/vhost.d/default;
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if $vhost.enable_debug_endpoint }}
|
||||||
|
{{ template "debug_location" (dict "GlobalConfig" $globals.config "Hostname" $hostname "VHost" $vhost) }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
{{- range $path, $vpath := $vhost.paths }}
|
{{- range $path, $vpath := $vhost.paths }}
|
||||||
{{- template "location" (dict
|
{{- template "location" (dict
|
||||||
"Path" $path
|
"Path" $path
|
||||||
@ -903,9 +972,9 @@ server {
|
|||||||
) }}
|
) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- if and (not (contains $vhost.paths "/")) (ne $globals.default_root_response "none")}}
|
{{- if and (not (contains $vhost.paths "/")) (ne $globals.config.default_root_response "none")}}
|
||||||
location / {
|
location / {
|
||||||
return {{ $globals.default_root_response }};
|
return {{ $globals.config.default_root_response }};
|
||||||
}
|
}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
}
|
}
|
||||||
|
36
test/test_debug_endpoint/test_global.py
Normal file
36
test/test_debug_endpoint/test_global.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import json
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
def test_debug_endpoint_is_enabled_globally(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://enabled.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 200
|
||||||
|
r = nginxproxy.get("http://stripped.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_debug_endpoint_response_contains_expected_values(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://enabled.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 200
|
||||||
|
try:
|
||||||
|
jsonResponse = json.loads(r.text)
|
||||||
|
except ValueError as err:
|
||||||
|
pytest.fail("Failed to parse debug endpoint response as JSON: %s" % err, pytrace=False)
|
||||||
|
assert jsonResponse["global"]["enable_debug_endpoint"] == "true"
|
||||||
|
assert jsonResponse["vhost"]["enable_debug_endpoint"] == True
|
||||||
|
|
||||||
|
|
||||||
|
def test_debug_endpoint_pahts_stripped_if_response_too_long(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://stripped.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 200
|
||||||
|
try:
|
||||||
|
jsonResponse = json.loads(r.text)
|
||||||
|
except ValueError as err:
|
||||||
|
pytest.fail("Failed to parse debug endpoint response as JSON: %s" % err, pytrace=False)
|
||||||
|
if "paths" in jsonResponse["vhost"]:
|
||||||
|
pytest.fail("Expected paths to be stripped from debug endpoint response", pytrace=False)
|
||||||
|
assert jsonResponse["warning"] == "Virtual paths configuration for this hostname is too large and has been stripped from response."
|
||||||
|
|
||||||
|
|
||||||
|
def test_debug_endpoint_is_disabled_per_container(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://disabled.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 404
|
54
test/test_debug_endpoint/test_global.yml
Normal file
54
test/test_debug_endpoint/test_global.yml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
services:
|
||||||
|
nginx-proxy:
|
||||||
|
image: nginxproxy/nginx-proxy:test
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
environment:
|
||||||
|
DEBUG_ENDPOINT: "true"
|
||||||
|
|
||||||
|
debug_enabled:
|
||||||
|
image: web
|
||||||
|
expose:
|
||||||
|
- "81"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: 81
|
||||||
|
VIRTUAL_HOST: enabled.debug.nginx-proxy.example
|
||||||
|
|
||||||
|
debug_stripped:
|
||||||
|
image: web
|
||||||
|
expose:
|
||||||
|
- "82"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: 82
|
||||||
|
VIRTUAL_HOST_MULTIPORTS: |-
|
||||||
|
stripped.debug.nginx-proxy.example:
|
||||||
|
"/1":
|
||||||
|
"/2":
|
||||||
|
"/3":
|
||||||
|
"/4":
|
||||||
|
"/5":
|
||||||
|
"/6":
|
||||||
|
"/7":
|
||||||
|
"/8":
|
||||||
|
"/9":
|
||||||
|
"/10":
|
||||||
|
"/11":
|
||||||
|
"/12":
|
||||||
|
"/13":
|
||||||
|
"/14":
|
||||||
|
"/15":
|
||||||
|
"/16":
|
||||||
|
"/17":
|
||||||
|
"/18":
|
||||||
|
"/19":
|
||||||
|
"/20":
|
||||||
|
|
||||||
|
debug_disabled:
|
||||||
|
image: web
|
||||||
|
expose:
|
||||||
|
- "83"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: 83
|
||||||
|
VIRTUAL_HOST: disabled.debug.nginx-proxy.example
|
||||||
|
labels:
|
||||||
|
com.github.nginx-proxy.nginx-proxy.debug-endpoint: "false"
|
24
test/test_debug_endpoint/test_per_container.py
Normal file
24
test/test_debug_endpoint/test_per_container.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import json
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
def test_debug_endpoint_is_disabled_globally(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://disabled1.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 404
|
||||||
|
r = nginxproxy.get("http://disabled2.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
|
def test_debug_endpoint_is_enabled_per_container(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://enabled.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_debug_endpoint_response_contains_expected_values(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://enabled.debug.nginx-proxy.example/nginx-proxy-debug")
|
||||||
|
assert r.status_code == 200
|
||||||
|
try:
|
||||||
|
jsonResponse = json.loads(r.text)
|
||||||
|
except ValueError as err:
|
||||||
|
pytest.fail("Failed to parse debug endpoint response as JSON:: %s" % err, pytrace=False)
|
||||||
|
assert jsonResponse["global"]["enable_debug_endpoint"] == "false"
|
||||||
|
assert jsonResponse["vhost"]["enable_debug_endpoint"] == True
|
32
test/test_debug_endpoint/test_per_container.yml
Normal file
32
test/test_debug_endpoint/test_per_container.yml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
services:
|
||||||
|
nginx-proxy:
|
||||||
|
image: nginxproxy/nginx-proxy:test
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
|
||||||
|
debug_disabled1:
|
||||||
|
image: web
|
||||||
|
expose:
|
||||||
|
- "81"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: 81
|
||||||
|
VIRTUAL_HOST: disabled1.debug.nginx-proxy.example
|
||||||
|
|
||||||
|
debug_disabled2:
|
||||||
|
image: web
|
||||||
|
expose:
|
||||||
|
- "82"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: 82
|
||||||
|
VIRTUAL_HOST: disabled2.debug.nginx-proxy.example
|
||||||
|
|
||||||
|
|
||||||
|
debug_enabled:
|
||||||
|
image: web
|
||||||
|
expose:
|
||||||
|
- "83"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: 83
|
||||||
|
VIRTUAL_HOST: enabled.debug.nginx-proxy.example
|
||||||
|
labels:
|
||||||
|
com.github.nginx-proxy.nginx-proxy.debug-endpoint: "true"
|
Loading…
x
Reference in New Issue
Block a user