From b533994b09bf7b824f4954f1457874af1aa34aec Mon Sep 17 00:00:00 2001 From: Rodrigo Aguilera Date: Thu, 19 Apr 2018 20:54:01 +0200 Subject: [PATCH] Add support for path-based routing. --- README.md | 4 +++- nginx.tmpl | 26 ++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9d19f82..5b87195 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,8 @@ You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a The full request URI will be forwarded to the serving container in the `X-Original-URI` header. +When you want to forward many paths to the same container you can set the variable using a regular expresion. For example VIRTUAL_PATH="~^/(path1|path2)" will answer to requests that start with /path1 or /path2. + ### Multiple Networks With the addition of [overlay networking](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) in Docker 1.9, your `nginx-proxy` container may need to connect to backend containers on multiple networks. By default, if you don't pass the `--net` flag when your `nginx-proxy` container is created, it will only be attached to the default `bridge` network. This means that it will not be able to connect to containers on networks other than `bridge`. @@ -329,7 +331,7 @@ 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-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; -proxy_set_header X-Forwarded-Path $request_uri; +proxy_set_header X-Original-URI $request_uri; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; diff --git a/nginx.tmpl b/nginx.tmpl index ac52b61..23d9c62 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -27,7 +27,7 @@ location {{ .Path }} { include fastcgi.conf; fastcgi_pass {{ trim .Upstream }}; {{ else }} - proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}/; + proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}; {{ end }} {{ if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }} @@ -44,15 +44,14 @@ location {{ .Path }} { {{ end }} {{ define "upstream-definition" }} + {{ $networks := .Networks }} upstream {{ .Upstream }} { {{ range $container := .Containers }} {{ $addrLen := len $container.Addresses }} - {{ $networks := .Networks }} {{ range $knownNetwork := $networks }} {{ range $containerNetwork := $container.Networks }} {{ if (and (ne $containerNetwork.Name "ingress") (or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name "host"))) }} - ## Can be connect with "{{ $containerNetwork.Name }}" network - + ## Can be connected with "{{ $containerNetwork.Name }}" network {{/* If only 1 port exposed, use that */}} {{ if eq $addrLen 1 }} {{ $address := index $container.Addresses 0 }} @@ -63,6 +62,9 @@ location {{ .Path }} { {{ $address := where $container.Addresses "Port" $port | first }} {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} {{ end }} + {{ else }} + # Cannot connect to network of this container + server 127.0.0.1 down; {{ end }} {{ end }} {{ end }} @@ -167,16 +169,20 @@ server { {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }} +{{ $host := trim $host }} +{{ $is_regexp := hasPrefix "~" $host }} +{{ $upstream_name := when $is_regexp (sha1 $host) $host }} + {{ $paths := groupBy $containers "Env.VIRTUAL_PATH" }} {{ $nPaths := len $paths }} {{ if eq $nPaths 0 }} # {{ $host }} - {{ template "upstream-definition" (dict "Upstream" $host "Containers" $containers "Networks" (json $CurrentContainer.Networks)) }} + {{ template "upstream-definition" (dict "Upstream" $upstream_name "Containers" $containers "Networks" $CurrentContainer.Networks) }} {{ else }} {{ range $path, $containers := $paths }} {{ $sum := sha1 $path }} - {{ $upstream := printf "%s-%s" $host $sum }} + {{ $upstream := printf "%s-%s" $upstream_name $sum }} # {{ $host }}{{ $path }} {{ template "upstream-definition" (dict "Upstream" $upstream "Containers" $containers "Networks" $CurrentContainer.Networks) }} {{ end }} @@ -307,11 +313,11 @@ server { {{ end }} {{ if eq $nPaths 0 }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $host "Host" $host "VHostRoot" $vhost_root) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "VHostRoot" $vhost_root) }} {{ else }} {{ range $path, $containers := $paths }} {{ $sum := sha1 $path }} - {{ $upstream := printf "%s-%s" $host $sum }} + {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "VHostRoot" $vhost_root) }} {{ end }} {{ end }} @@ -341,11 +347,11 @@ server { {{ end }} {{ if eq $nPaths 0 }} - {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $host "Host" $host "VHostRoot" $vhost_root) }} + {{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "VHostRoot" $vhost_root) }} {{ else }} {{ range $path, $containers := $paths }} {{ $sum := sha1 $path }} - {{ $upstream := printf "%s-%s" $host $sum }} + {{ $upstream := printf "%s-%s" $upstream_name $sum }} {{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "VHostRoot" $vhost_root) }} {{ end }} {{ end }}