mirror of
https://github.com/thib8956/nginx-proxy
synced 2025-04-16 18:51:01 +00:00
feat: Add custom location block to virtual paths
This features allows the custom location blocks to be added to the virtual path based routing. The custom config can be specified for each container individually.
This commit is contained in:
parent
4b85e95824
commit
33eab70d32
@ -120,6 +120,7 @@ You can also use wildcards at the beginning and the end of host name, like `*.ba
|
||||
### Path-based Routing
|
||||
|
||||
You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`.
|
||||
It is also possible to specify multiple paths with regex locations like `VIRTUAL_PATH=~^/(app1|alternative1)/`. For further details see the nginx documentation on location blocks. This is not compatible with `VIRTUAL_DEST`.
|
||||
|
||||
The full request URI will be forwarded to the serving container in the `X-Forwarded-Path` header.
|
||||
|
||||
@ -139,6 +140,14 @@ $ docker run -d -e VIRTUAL_HOST=example.tld -e VIRTUAL_PATH=/app1/ -e VIRTUAL_DE
|
||||
|
||||
In this example, the incoming request `http://example.tld/app1/foo` will be proxied as `http://app1/foo` instead of `http://app1/app1/foo`.
|
||||
|
||||
#### Per-VIRTUAL_PATH location configuration
|
||||
|
||||
The same options as from [Per-VIRTUAL_HOST location configuration](#Per-VIRTUAL_HOST-location-configuration) are available on a `VIRTUAL_PATH` basis.
|
||||
The only difference is that the filename gets an additional block `HASH=$(echo -n $VIRTUAL_PATH | sha1sum | awk '{ print $1 }')`. This is the sha1-hash of the `VIRTUAL_PATH` (no newline). This is done filename sanitization purposes.
|
||||
The used filename is `${VIRTUAL_HOST}_${HASH}_location`
|
||||
|
||||
The filename of the previous example would be `example.tld_8610f6c344b4096614eab6e09d58885349f42faf_location`.
|
||||
|
||||
#### DEFAULT_ROOT
|
||||
|
||||
This environment variable of the nginx proxy container can be used to customize the return error page if no matching path is found. Furthermore it is possible to use anything which is compatible with the `return` statement of nginx.
|
||||
|
@ -72,6 +72,8 @@ location {{ .Path }} {
|
||||
|
||||
{{ if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }}
|
||||
include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}};
|
||||
{{ else if (exists (printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) )) }}
|
||||
include {{ printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) }};
|
||||
{{ else if (exists "/etc/nginx/vhost.d/default_location") }}
|
||||
include /etc/nginx/vhost.d/default_location;
|
||||
{{ end }}
|
||||
|
1
test/test_virtual-path/alternate.conf
Normal file
1
test/test_virtual-path/alternate.conf
Normal file
@ -0,0 +1 @@
|
||||
rewrite ^/(web3|alt)/(.*) /$2 break;
|
1
test/test_virtual-path/bar.conf
Normal file
1
test/test_virtual-path/bar.conf
Normal file
@ -0,0 +1 @@
|
||||
add_header X-test bar;
|
1
test/test_virtual-path/foo.conf
Normal file
1
test/test_virtual-path/foo.conf
Normal file
@ -0,0 +1 @@
|
||||
add_header X-test f00;
|
@ -4,3 +4,35 @@ def test_default_root_response(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://nginx-proxy.test/")
|
||||
assert r.status_code == 418
|
||||
|
||||
@pytest.mark.parametrize("stub,header", [
|
||||
("nginx-proxy.test/web1", "bar"),
|
||||
("foo.nginx-proxy.test", "f00"),
|
||||
])
|
||||
def test_custom_applies(docker_compose, nginxproxy, stub, header):
|
||||
r = nginxproxy.get(f"http://{stub}/port")
|
||||
assert r.status_code == 200
|
||||
assert "X-test" in r.headers
|
||||
assert header == r.headers["X-test"]
|
||||
|
||||
@pytest.mark.parametrize("stub,code", [
|
||||
("nginx-proxy.test/foo", 418),
|
||||
("nginx-proxy.test/web2", 200),
|
||||
("nginx-proxy.test/web3", 200),
|
||||
("bar.nginx-proxy.test", 503),
|
||||
])
|
||||
def test_custom_does_not_apply(docker_compose, nginxproxy, stub, code):
|
||||
r = nginxproxy.get(f"http://{stub}/port")
|
||||
assert r.status_code == code
|
||||
assert "X-test" not in r.headers
|
||||
|
||||
@pytest.mark.parametrize("stub,port", [
|
||||
("nginx-proxy.test/web1", 81),
|
||||
("nginx-proxy.test/web2", 82),
|
||||
("nginx-proxy.test/web3", 83),
|
||||
("nginx-proxy.test/alt", 83),
|
||||
])
|
||||
def test_alternate(docker_compose, nginxproxy, stub, port):
|
||||
r = nginxproxy.get(f"http://{stub}/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == f"answer from port {port}\n"
|
||||
|
||||
|
@ -1,3 +1,12 @@
|
||||
|
||||
foo:
|
||||
image: web
|
||||
expose:
|
||||
- "42"
|
||||
environment:
|
||||
WEB_PORTS: "42"
|
||||
VIRTUAL_HOST: "foo.nginx-proxy.test"
|
||||
|
||||
web1:
|
||||
image: web
|
||||
expose:
|
||||
@ -18,6 +27,15 @@ web2:
|
||||
VIRTUAL_PATH: "/web2/"
|
||||
VIRTUAL_DEST: "/"
|
||||
|
||||
web3:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
VIRTUAL_HOST: "nginx-proxy.test"
|
||||
VIRTUAL_PATH: "~ ^/(web3|alt)/"
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
environment:
|
||||
@ -25,3 +43,7 @@ sut:
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ../lib/ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem:ro
|
||||
- ./foo.conf:/etc/nginx/vhost.d/foo.nginx-proxy.test:ro
|
||||
- ./bar.conf:/etc/nginx/vhost.d/nginx-proxy.test_918d687a929083edd0c7224ee2293e0e7c062ab4_location:ro
|
||||
- ./alternate.conf:/etc/nginx/vhost.d/nginx-proxy.test_7fb22b74bbdf907425dbbad18e4462565cada230_location:ro
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user