diff --git a/nginx.tmpl b/nginx.tmpl index 9eb9520..d14b917 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -17,6 +17,55 @@ {{ end }} {{ end }} +{{ define "location" }} +location {{ .Path }} { + {{ if eq .Proto "uwsgi" }} + include uwsgi_params; + uwsgi_pass {{ trim .Proto }}://{{ trim .Upstream }}; + {{ else }} + proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}/; + {{ end }} + + {{ if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }} + auth_basic "Restricted {{ .Host }}"; + auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" .Host) }}; + {{ end }} + + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}}; + {{ else if (exists "/etc/nginx/vhost.d/default_location") }} + include /etc/nginx/vhost.d/default_location; + {{ end }} +} +{{ end }} + +{{ define "upstream-definition" }} + upstream {{ .Upstream }} { + {{ range $container := .Containers }} + {{ $addrLen := len $container.Addresses }} + {{ $networks := .Networks }} + {{ range $knownNetwork := $networks }} + {{ range $containerNetwork := $container.Networks }} + {{ if eq $knownNetwork.Name $containerNetwork.Name }} + ## Can be connect with "{{ $containerNetwork.Name }}" network + + {{/* If only 1 port exposed, use that */}} + {{ if eq $addrLen 1 }} + {{ $address := index $container.Addresses 0 }} + {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} + {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}} + {{ else }} + {{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }} + {{ $address := where $container.Addresses "Port" $port | first }} + {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} + {{ end }} + {{ end }} + {{ end }} + {{ end }} + {{ end }} + } +{{ end }} + # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { @@ -38,6 +87,7 @@ log_format vhost '$host $remote_addr - $remote_user [$time_local] ' '"$http_referer" "$http_user_agent"'; access_log off; +error_log /dev/stderr; {{ if (exists "/etc/nginx/proxy.conf") }} include /etc/nginx/proxy.conf; @@ -51,6 +101,7 @@ 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-Proto $proxy_x_forwarded_proto; +proxy_set_header X-Forwarded-Path $request_uri; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; @@ -78,30 +129,20 @@ server { {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }} -upstream {{ $host }} { -{{ range $container := $containers }} - {{ $addrLen := len $container.Addresses }} +{{ $paths := groupBy $containers "Env.VIRTUAL_PATH" }} +{{ $nPaths := len $paths }} - {{ range $knownNetwork := $CurrentContainer.Networks }} - {{ range $containerNetwork := $container.Networks }} - {{ if eq $knownNetwork.Name $containerNetwork.Name }} - ## Can be connect with "{{ $containerNetwork.Name }}" network - - {{/* If only 1 port exposed, use that */}} - {{ if eq $addrLen 1 }} - {{ $address := index $container.Addresses 0 }} - {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} - {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}} - {{ else }} - {{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }} - {{ $address := where $container.Addresses "Port" $port | first }} - {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} - {{ end }} - {{ end }} - {{ end }} +{{ if eq $nPaths 0 }} + # {{ $host }} + {{ template "upstream-definition" (dict "Upstream" $host "Containers" $containers "Networks" (json $CurrentContainer.Networks)) }} +{{ else }} + {{ range $path, $containers := $paths }} + {{ $sum := sha1 $path }} + {{ $upstream := printf "%s-%s" $host $sum }} + # {{ $host }}{{ $path }} + {{ template "upstream-definition" (dict "Upstream" $upstream "Containers" $containers "Networks" $CurrentContainer.Networks) }} {{ end }} {{ end }} -} {{ $default_host := or ($.Env.DEFAULT_HOST) "" }} {{ $default_server := index (dict $host "" $default_host "default_server") $host }} @@ -167,24 +208,16 @@ server { {{ else if (exists "/etc/nginx/vhost.d/default") }} include /etc/nginx/vhost.d/default; {{ end }} - - location / { - {{ if eq $proto "uwsgi" }} - include uwsgi_params; - uwsgi_pass {{ trim $proto }}://{{ trim $host }}; - {{ else }} - proxy_pass {{ trim $proto }}://{{ trim $host }}; + + {{ if eq $nPaths 0 }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $host "Host" $host) }} + {{ else }} + {{ range $path, $containers := $paths }} + {{ $sum := sha1 $path }} + {{ $upstream := printf "%s-%s" $host $sum }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host) }} {{ end }} - {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} - auth_basic "Restricted {{ $host }}"; - auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; - {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/nginx/vhost.d/default_location") }} - include /etc/nginx/vhost.d/default_location; - {{ end }} - } + {{ end }} } {{ end }} @@ -202,23 +235,15 @@ server { include /etc/nginx/vhost.d/default; {{ end }} - location / { - {{ if eq $proto "uwsgi" }} - include uwsgi_params; - uwsgi_pass {{ trim $proto }}://{{ trim $host }}; - {{ else }} - proxy_pass {{ trim $proto }}://{{ trim $host }}; + {{ if eq $nPaths 0 }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $host "Host" $host) }} + {{ else }} + {{ range $path, $containers := $paths }} + {{ $sum := sha1 $path }} + {{ $upstream := printf "%s-%s" $host $sum }} + {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host) }} {{ end }} - {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} - auth_basic "Restricted {{ $host }}"; - auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; - {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/nginx/vhost.d/default_location") }} - include /etc/nginx/vhost.d/default_location; - {{ end }} - } + {{ end }} } {{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}