From c24a39711b5d0107bd2af9c8e764bf75fdd46297 Mon Sep 17 00:00:00 2001 From: Stefan Fussenegger Date: Fri, 31 Mar 2017 12:14:49 +0200 Subject: [PATCH] added VIRTUAL_PATH support --- nginx.tmpl | 135 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 59 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index a5b1d32..362c6cd 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,5 +1,32 @@ {{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }} +{{ define "upstream-block" }} +upstream {{ .Upstream }} { +{{ range $container := .Containers }} + {{ $addrLen := len $container.Addresses }} + + {{ 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 }} + {{ define "upstream" }} {{ if .Address }} {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} @@ -17,6 +44,24 @@ {{ end }} {{ end }} +{{ define "location" }} + location {{ .Path }} { + {{ if eq .Proto "uwsgi" }} + include uwsgi_params; + {{ end }} + proxy_pass {{ .Proto }}://{{ .Upstream }}; + {{ 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 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 { @@ -99,33 +144,19 @@ server { {{ end }} {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }} -{{ $is_regexp := hasPrefix "~" $host }} -{{ $upstream_name := when $is_regexp (sha1 $host) $host }} -# {{ $host }} -upstream {{ $upstream_name }} { -{{ range $container := $containers }} - {{ $addrLen := len $container.Addresses }} - {{ 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 }} - {{ end }} +{{ range $path, $pathContainers := groupBy $containers "Env.VIRTUAL_PATH" }} +{{ $upstream_name := (sha1 (printf "%s%s" $host $path)) }} +# {{ $host }}{{ $path }} +{{ template "upstream-block" dict "Upstream" $upstream_name "Containers" $pathContainers "Networks" $CurrentContainer.Networks }} +{{ end }} + +{{ $defaultContainers := whereNotExist $containers "Env.VIRTUAL_PATH" }} +{{ if ne (len $defaultContainers) 0 }} +{{ $upstream_name := (sha1 (printf "%s" $host)) }} +# {{ $host }} +{{ template "upstream-block" dict "Upstream" $upstream_name "Containers" $defaultContainers "Networks" $CurrentContainer.Networks }} {{ end }} -} {{ $default_host := or ($.Env.DEFAULT_HOST) "" }} {{ $default_server := index (dict $host "" $default_host "default_server") $host }} @@ -198,23 +229,16 @@ server { include /etc/nginx/vhost.d/default; {{ end }} - location / { - {{ if eq $proto "uwsgi" }} - include uwsgi_params; - uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ else }} - proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ 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 }} - } + {{ range $path, $pathContainers := groupBy $containers "Env.VIRTUAL_PATH" }} + {{ $upstream_name := (sha1 (printf "%s%s" $host $path)) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Host" $host "Upstream" $upstream_name) }} + {{ end }} + + {{ $defaultContainers := whereNotExist $containers "Env.VIRTUAL_PATH" }} + {{ if ne (len $defaultContainers) 0 }} + {{ $upstream_name := (sha1 (printf "%s" $host)) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Host" $host "Upstream" $upstream_name) }} + {{ end }} } {{ end }} @@ -235,23 +259,16 @@ server { include /etc/nginx/vhost.d/default; {{ end }} - location / { - {{ if eq $proto "uwsgi" }} - include uwsgi_params; - uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ else }} - proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; - {{ 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 }} - } + {{ range $path, $pathContainers := groupBy $containers "Env.VIRTUAL_PATH" }} + {{ $upstream_name := (sha1 (printf "%s%s" $host $path)) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Host" $host "Upstream" $upstream_name) }} + {{ end }} + + {{ $defaultContainers := whereNotExist $containers "Env.VIRTUAL_PATH" }} + {{ if ne (len $defaultContainers) 0 }} + {{ $upstream_name := (sha1 (printf "%s" $host)) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Host" $host "Upstream" $upstream_name) }} + {{ end }} } {{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}