1
0
mirror of https://github.com/thib8956/nginx-proxy synced 2025-02-24 09:48:14 +00:00

Merge pull request #2159 from rhansen/refactor

chore: Factor out container IP:port lookup
This commit is contained in:
Nicolas Duchon 2023-02-09 08:01:26 +01:00 committed by GitHub
commit 41e025f0f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -26,6 +26,75 @@
# {{ .Name }} # {{ .Name }}
{{- end }} {{- end }}
{{- /*
* Template used as a function to get a container's IP address. This
* template only outputs debug comments; the IP address is "returned" by
* storing the value in the provided dot dict.
*
* The provided dot dict is expected to have the following entries:
* - "globals": Global values.
* - "container": The container's RuntimeContainer struct.
*
* The return value will be added to the dot dict with key "ip".
*/}}
{{- define "container_ip" }}
{{- $ip := "" }}
# networks:
{{- range sortObjectsByKeysAsc $.container.Networks "Name" }}
{{- if and (not (index $.globals.networks .Name)) (not $.globals.networks.host) }}
# {{ .Name }} (unreachable)
{{- continue }}
{{- end }}
{{- /*
* Do not emit multiple `server` directives for this container if it
* is reachable over multiple networks. This avoids accidentally
* inflating the effective round-robin weight of a server due to the
* redundant upstream addresses that nginx sees as belonging to
* distinct servers.
*/}}
{{- if $ip }}
# {{ .Name }} (ignored; reachable but redundant)
{{- continue }}
{{- end }}
# {{ .Name }} (reachable)
{{- if and . .IP }}
{{- $ip = .IP }}
{{- else }}
# /!\ No IP for this network!
{{- end }}
{{- else }}
# (none)
{{- end }}
# IP address: {{ if $ip }}{{ $ip }}{{ else }}(none usable){{ end }}
{{- $_ := set $ "ip" $ip }}
{{- end }}
{{- /*
* Template used as a function to get the port of the server in the given
* container. This template only outputs debug comments; the port is
* "returned" by storing the value in the provided dot dict.
*
* The provided dot dict is expected to have the following entries:
* - "container": The container's RuntimeContainer struct.
*
* The return value will be added to the dot dict with key "port".
*/}}
{{- define "container_port" }}
{{- /* If only 1 port exposed, use that as a default, else 80. */}}
# exposed ports:{{ range $.container.Addresses }} {{ .Port }}/{{ .Proto }}{{ else }} (none){{ end }}
{{- $default_port := when (eq (len $.container.Addresses) 1) (first $.container.Addresses).Port "80" }}
# default port: {{ $default_port }}
{{- $port := or $.container.Env.VIRTUAL_PORT $default_port }}
# using port: {{ $port }}
{{- $addr_obj := where $.container.Addresses "Port" $port | first }}
{{- if and $addr_obj $addr_obj.HostPort }}
# /!\ WARNING: Virtual port published on host. Clients
# might be able to bypass nginx-proxy and
# access the container's server directly.
{{- end }}
{{- $_ := set $ "port" $port }}
{{- end }}
{{- define "ssl_policy" }} {{- define "ssl_policy" }}
{{- if eq .ssl_policy "Mozilla-Modern" }} {{- if eq .ssl_policy "Mozilla-Modern" }}
ssl_protocols TLSv1.3; ssl_protocols TLSv1.3;
@ -119,50 +188,16 @@
{{- end }} {{- end }}
{{- define "upstream" }} {{- define "upstream" }}
{{- $networks := .Networks }}
upstream {{ .Upstream }} { upstream {{ .Upstream }} {
{{- $server_found := false }} {{- $server_found := false }}
{{- range $container := .Containers }} {{- range $container := .Containers }}
# Container: {{ $container.Name }} # Container: {{ $container.Name }}
{{- /* If only 1 port exposed, use that as a default, else 80 */}} {{- $args := dict "globals" $.globals "container" $container }}
{{- $defaultPort := (when (eq (len $container.Addresses) 1) (first $container.Addresses) (dict "Port" "80")).Port }} {{- template "container_ip" $args }}
{{- $ip := "" }} {{- $ip := $args.ip }}
{{- $port := (coalesce $container.Env.VIRTUAL_PORT $defaultPort) }} {{- $args := dict "container" $container }}
{{- $addr_obj := where $container.Addresses "Port" $port | first }} {{- template "container_port" $args }}
# Exposed ports:{{ range $container.Addresses }} {{ .Port }}/{{ .Proto }}{{ else }} (none){{ end }} {{- $port := $args.port }}
# Default virtual port: {{ $defaultPort }}
# VIRTUAL_PORT: {{ $container.Env.VIRTUAL_PORT }}
{{- if and $addr_obj $addr_obj.HostPort }}
# /!\ WARNING: Virtual port published on host. Clients might be able to
# bypass nginx-proxy and access the container's server
# directly.
{{- end }}
# Container networks:
{{- range $containerNetwork := sortObjectsByKeysAsc $container.Networks "Name" }}
{{- if and (not (index $networks $containerNetwork.Name)) (not $networks.host) }}
# {{ $containerNetwork.Name }} (unreachable)
{{- continue }}
{{- end }}
{{- /*
* Do not emit multiple `server` directives for this container
* if it is reachable over multiple networks. This avoids
* accidentally inflating the effective round-robin weight of
* this container due to the redundant upstreams that nginx sees
* as belonging to distinct servers.
*/}}
{{- if $ip }}
# {{ $containerNetwork.Name }} (ignored; reachable but redundant)
{{- continue }}
{{- end }}
# {{ $containerNetwork.Name }} (reachable)
{{- if and $containerNetwork $containerNetwork.IP }}
{{- $ip = $containerNetwork.IP }}
{{- else }}
# /!\ No IP for this network!
{{- end }}
{{- else }}
# (none)
{{- end }}
{{- if $ip }} {{- if $ip }}
{{- $server_found = true }} {{- $server_found = true }}
server {{ $ip }}:{{ $port }}; server {{ $ip }}:{{ $port }};
@ -296,7 +331,7 @@ server {
{{- $upstream = printf "%s-%s" $upstream $sum }} {{- $upstream = printf "%s-%s" $upstream $sum }}
{{- end }} {{- end }}
# {{ $host }}{{ $path }} # {{ $host }}{{ $path }}
{{ template "upstream" (dict "Upstream" $upstream "Containers" $containers "Networks" $globals.networks) }} {{ template "upstream" (dict "globals" $globals "Upstream" $upstream "Containers" $containers) }}
{{- end }} {{- end }}
{{- $default_host := or ($globals.Env.DEFAULT_HOST) "" }} {{- $default_host := or ($globals.Env.DEFAULT_HOST) "" }}