From edfedca801a2f97c8c570a1b0debdb1155d40397 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Mon, 19 Oct 2015 19:12:36 -0700 Subject: [PATCH] Support paths with VIRTUAL_PATH --- Dockerfile | 2 +- nginx.tmpl | 92 +++++++++++++++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/Dockerfile b/Dockerfile index c35c777..b036e8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ RUN wget -P /usr/local/bin https://godist.herokuapp.com/projects/ddollar/forego/releases/current/linux-amd64/forego \ && chmod u+x /usr/local/bin/forego -ENV DOCKER_GEN_VERSION 0.4.2 +ENV DOCKER_GEN_VERSION 0.4.3 RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ && tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ diff --git a/nginx.tmpl b/nginx.tmpl index c2d61ae..5a4bf40 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,3 +1,21 @@ +{{ define "upstream-block" }} +upstream {{ .Host }}{{ .Suffix }} { +{{ range $container := .Containers }} + {{ $addrLen := len $container.Addresses }} + {{/* If only 1 port exposed, use that */}} + {{ if eq $addrLen 1 }} + {{ $address := index $container.Addresses 0 }} + {{ template "upstream" (dict "Container" $container "Address" $address) }} + {{/* 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) }} + {{ 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 */}} @@ -15,6 +33,21 @@ {{ end }} {{ end }} +{{ define "location" }} + location {{ .Path }} { + proxy_pass {{ .Proto }}://{{ .Host }}{{ .Suffix }}; + {{ 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 { @@ -72,23 +105,16 @@ server { {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }} -{{ $host := trim $host }} +{{ $hostParts := splitN (trim $host) "/" 2 }} +{{ $host := index $hostParts 0 }} +{{ $hasDefaultPath := eq (len $hostParts) 1 }} -upstream {{ $host }} { -{{ range $container := $containers }} - {{ $addrLen := len $container.Addresses }} - {{/* If only 1 port exposed, use that */}} - {{ if eq $addrLen 1 }} - {{ $address := index $container.Addresses 0 }} - {{ template "upstream" (dict "Container" $container "Address" $address) }} - {{/* 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) }} - {{ end }} +{{ if $hasDefaultPath }} +{{ template "upstream-block" dict "Host" $host "Suffix" "" "Containers" $containers }} +{{ else }} +{{ $path := printf "/%s" (index $hostParts 1) }} +{{ template "upstream-block" dict "Host" $host "Suffix" (printf "-%s" (sha1 $path)) "Containers" $containers }} {{ end }} -} {{ $default_host := or ($.Env.DEFAULT_HOST) "" }} {{ $default_server := index (dict $host "" $default_host "default_server") $host }} @@ -145,18 +171,12 @@ server { include /etc/nginx/vhost.d/default; {{ end }} - location / { - proxy_pass {{ $proto }}://{{ $host }}; - {{ 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 }} - } + {{ if $hasDefaultPath }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Host" $host "Suffix" "" ) }} + {{ else }} + {{ $path := printf "/%s" (index $hostParts 1) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Host" $host "Suffix" (printf "-%s" (sha1 $path)) ) }} + {{ end }} } {{ else }} @@ -171,18 +191,12 @@ server { include /etc/nginx/vhost.d/default; {{ end }} - location / { - proxy_pass {{ $proto }}://{{ $host }}; - {{ 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 }} - } + {{ if $hasDefaultPath }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Host" $host "Suffix" "" ) }} + {{ else }} + {{ $path := printf "/%s" (index $hostParts 1) }} + {{ template "location" (dict "Path" $path "Proto" $proto "Host" $host "Suffix" (printf "-%s" (sha1 $path)) ) }} + {{ end }} } {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}