mirror of
https://github.com/thib8956/nginx-proxy
synced 2025-08-23 16:01:57 +00:00
Merge pull request #2279 from Knapoc/network-segregation-seperate-containers
feat: allow nginx / docker-gen network segregation
This commit is contained in:
@@ -1136,25 +1136,65 @@ I'm 5b129ab83266
|
|||||||
|
|
||||||
To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/nginx-proxy/nginx-proxy/blob/main/nginx.tmpl) on your host system.
|
To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/nginx-proxy/nginx-proxy/blob/main/nginx.tmpl) on your host system.
|
||||||
|
|
||||||
First start nginx with a volume:
|
First start nginx with a volume mounted to `/etc/nginx/conf.d`:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
|
docker run --detach \
|
||||||
|
--name nginx \
|
||||||
|
--publish 80:80 \
|
||||||
|
--volume /tmp/nginx:/etc/nginx/conf.d \
|
||||||
|
nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
Then start the docker-gen container with the shared volume and template:
|
Then start the docker-gen container with the shared volume and template:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
docker run --volumes-from nginx \
|
docker run --detach \
|
||||||
-v /var/run/docker.sock:/tmp/docker.sock:ro \
|
--name docker-gen \
|
||||||
-v $(pwd):/etc/docker-gen/templates \
|
--volumes-from nginx \
|
||||||
-t nginxproxy/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
|
||||||
|
--volume $(pwd):/etc/docker-gen/templates \
|
||||||
|
nginxproxy/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, start your containers with `VIRTUAL_HOST` environment variables.
|
Finally, start your containers with `VIRTUAL_HOST` environment variables.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
docker run -e VIRTUAL_HOST=foo.bar.com ...
|
docker run --env VIRTUAL_HOST=foo.bar.com ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Network segregation
|
||||||
|
|
||||||
|
To allow for network segregation of the nginx and docker-gen containers, the label `com.github.nginx-proxy.nginx-proxy.nginx` must be applied to the nginx container, otherwise it is assumed that nginx and docker-gen share the same network:
|
||||||
|
|
||||||
|
```console
|
||||||
|
docker run --detach \
|
||||||
|
--name nginx \
|
||||||
|
--publish 80:80 \
|
||||||
|
--label "com.github.nginx-proxy.nginx-proxy.nginx" \
|
||||||
|
--volume /tmp/nginx:/etc/nginx/conf.d \
|
||||||
|
nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
Network segregation make it possible to run the docker-gen container in an [internal network](https://docs.docker.com/reference/cli/docker/network/create/#internal), unreachable from the outside.
|
||||||
|
|
||||||
|
You can also customise the label being used by docker-gen to find the nginx container with the `NGINX_CONTAINER_LABEL`environment variable (on the docker-gen container):
|
||||||
|
|
||||||
|
```console
|
||||||
|
docker run --detach \
|
||||||
|
--name docker-gen \
|
||||||
|
--volumes-from nginx \
|
||||||
|
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
|
||||||
|
--volume $(pwd):/etc/docker-gen/templates \
|
||||||
|
--env "NGINX_CONTAINER_LABEL=com.github.foobarbuzz" \
|
||||||
|
nginxproxy/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
docker run --detach \
|
||||||
|
--name nginx \
|
||||||
|
--publish 80:80 \
|
||||||
|
--label "com.github.foobarbuzz" \
|
||||||
|
--volume "/tmp/nginx:/etc/nginx/conf.d" \
|
||||||
|
nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
⬆️ [back to table of contents](#table-of-contents)
|
⬆️ [back to table of contents](#table-of-contents)
|
||||||
|
31
nginx.tmpl
31
nginx.tmpl
@@ -10,10 +10,10 @@
|
|||||||
{{- $_ := set $globals "containers" $ }}
|
{{- $_ := set $globals "containers" $ }}
|
||||||
{{- $_ := set $globals "Env" $.Env }}
|
{{- $_ := set $globals "Env" $.Env }}
|
||||||
{{- $_ := set $globals "Docker" $.Docker }}
|
{{- $_ := set $globals "Docker" $.Docker }}
|
||||||
{{- $_ := set $globals "CurrentContainer" (where $globals.containers "ID" $globals.Docker.CurrentContainerID | first) }}
|
|
||||||
|
|
||||||
{{- $config := dict }}
|
{{- $config := dict }}
|
||||||
{{- $_ := set $config "nginx_proxy_version" $.Env.NGINX_PROXY_VERSION }}
|
{{- $_ := set $config "nginx_proxy_version" $.Env.NGINX_PROXY_VERSION }}
|
||||||
|
{{- $_ := set $config "nginx_container_label" ($.Env.NGINX_CONTAINER_LABEL | default "com.github.nginx-proxy.nginx-proxy.nginx") }}
|
||||||
{{- $_ := set $config "default_cert_ok" (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
|
{{- $_ := set $config "default_cert_ok" (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
|
||||||
{{- $_ := set $config "external_http_port" ($globals.Env.HTTP_PORT | default "80") }}
|
{{- $_ := set $config "external_http_port" ($globals.Env.HTTP_PORT | default "80") }}
|
||||||
{{- $_ := set $config "external_https_port" ($globals.Env.HTTPS_PORT | default "443") }}
|
{{- $_ := set $config "external_https_port" ($globals.Env.HTTPS_PORT | default "443") }}
|
||||||
@@ -44,26 +44,29 @@
|
|||||||
|
|
||||||
{{- $_ := set $globals "vhosts" (dict) }}
|
{{- $_ := set $globals "vhosts" (dict) }}
|
||||||
{{- $_ := set $globals "networks" (dict) }}
|
{{- $_ := set $globals "networks" (dict) }}
|
||||||
# Networks available to the container running docker-gen (which are assumed to
|
|
||||||
# match the networks available to the container running nginx):
|
{{- $currentContainer := where $globals.containers "ID" $globals.Docker.CurrentContainerID | first }}
|
||||||
|
{{- $labeledContainer := whereLabelExists $globals.containers $globals.config.nginx_container_label | first }}
|
||||||
|
{{- $_ := set $globals "NetworkContainer" ($labeledContainer | default $currentContainer) }}
|
||||||
|
# Networks available to the container labeled "{{ $globals.config.nginx_container_label }}" or the one running docker-gen
|
||||||
|
# (which are assumed to match the networks available to the container running nginx):
|
||||||
{{- /*
|
{{- /*
|
||||||
* Note: $globals.CurrentContainer may be nil in some circumstances due to
|
* Note:
|
||||||
* <https://github.com/nginx-proxy/docker-gen/issues/458>. For more context
|
* $globals.NetworkContainer may be nil in some circumstances due to https://github.com/nginx-proxy/docker-gen/issues/458.
|
||||||
* see <https://github.com/nginx-proxy/nginx-proxy/issues/2189>.
|
* For more context see https://github.com/nginx-proxy/nginx-proxy/issues/2189.
|
||||||
*/}}
|
*/}}
|
||||||
{{- if $globals.CurrentContainer }}
|
{{- if $globals.NetworkContainer }}
|
||||||
{{- range sortObjectsByKeysAsc $globals.CurrentContainer.Networks "Name" }}
|
{{- range sortObjectsByKeysAsc $globals.NetworkContainer.Networks "Name" }}
|
||||||
{{- $_ := set $globals.networks .Name . }}
|
{{- $_ := set $globals.networks .Name . }}
|
||||||
# {{ .Name }}
|
# {{ .Name }}
|
||||||
{{- else }}
|
{{- else }}
|
||||||
# (none)
|
# (none)
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- else }}
|
{{- else }}
|
||||||
# /!\ WARNING: Failed to find the Docker container running docker-gen. All
|
# /!\ WARNING: Failed to find the Docker container labeled "{{ $globals.config.nginx_container_label }}" or the one running docker-gen.
|
||||||
# upstream (backend) application containers will appear to be
|
# All upstream (backend) application containers will appear to be unreachable.
|
||||||
# unreachable. Try removing the -only-exposed and -only-published
|
# Try removing the -only-exposed and -only-published arguments to docker-gen if you pass either of those.
|
||||||
# arguments to docker-gen if you pass either of those. See
|
# See https://github.com/nginx-proxy/docker-gen/issues/458.
|
||||||
# <https://github.com/nginx-proxy/docker-gen/issues/458>.
|
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- /*
|
{{- /*
|
||||||
@@ -97,7 +100,7 @@
|
|||||||
{{- $ipv4 = "127.0.0.1" }}
|
{{- $ipv4 = "127.0.0.1" }}
|
||||||
{{- continue }}
|
{{- continue }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- range sortObjectsByKeysAsc $.globals.CurrentContainer.Networks "Name" }}
|
{{- range sortObjectsByKeysAsc $.globals.NetworkContainer.Networks "Name" }}
|
||||||
{{- if and . .Gateway (not .Internal) }}
|
{{- if and . .Gateway (not .Internal) }}
|
||||||
# container is in host network mode, using {{ .Name }} gateway IP
|
# container is in host network mode, using {{ .Name }} gateway IP
|
||||||
{{- $ipv4 = .Gateway }}
|
{{- $ipv4 = .Gateway }}
|
||||||
|
@@ -0,0 +1,45 @@
|
|||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
private:
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
nginx_conf:
|
||||||
|
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx-proxy-nginx:
|
||||||
|
image: nginx
|
||||||
|
container_name: nginx
|
||||||
|
volumes:
|
||||||
|
- nginx_conf:/etc/nginx/conf.d:ro
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- "com.github.nginx-proxy.nginx-proxy.foobarbuzz"
|
||||||
|
|
||||||
|
nginx-proxy-dockergen:
|
||||||
|
image: nginxproxy/docker-gen
|
||||||
|
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
- ../../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
|
||||||
|
- nginx_conf:/etc/nginx/conf.d
|
||||||
|
environment:
|
||||||
|
NGINX_CONTAINER_LABEL: "com.github.nginx-proxy.nginx-proxy.foobarbuzz"
|
||||||
|
networks:
|
||||||
|
- private
|
||||||
|
|
||||||
|
web:
|
||||||
|
image: web
|
||||||
|
container_name: whoami2
|
||||||
|
expose:
|
||||||
|
- "80"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: "80"
|
||||||
|
VIRTUAL_HOST: whoami2.nginx.container.docker
|
||||||
|
networks:
|
||||||
|
- proxy
|
@@ -0,0 +1,27 @@
|
|||||||
|
import docker
|
||||||
|
import pytest
|
||||||
|
from packaging.version import Version
|
||||||
|
|
||||||
|
|
||||||
|
raw_version = docker.from_env().version()["Version"]
|
||||||
|
pytestmark = pytest.mark.skipif(
|
||||||
|
Version(raw_version) < Version("1.13"),
|
||||||
|
reason="Docker compose syntax v3 requires docker engine v1.13 or later (got {raw_version})"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unknown_virtual_host_is_503(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://unknown.nginx.container.docker/")
|
||||||
|
assert r.status_code == 503
|
||||||
|
|
||||||
|
|
||||||
|
def test_forwards_to_whoami(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://whoami2.nginx.container.docker/")
|
||||||
|
assert r.status_code == 200
|
||||||
|
whoami_container = docker_compose.containers.get("whoami2")
|
||||||
|
assert r.text == f"I'm {whoami_container.id[:12]}\n"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import doctest
|
||||||
|
doctest.testmod()
|
@@ -0,0 +1,43 @@
|
|||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
private:
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
nginx_conf:
|
||||||
|
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx-proxy-nginx:
|
||||||
|
image: nginx
|
||||||
|
container_name: nginx
|
||||||
|
volumes:
|
||||||
|
- nginx_conf:/etc/nginx/conf.d:ro
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- "com.github.nginx-proxy.nginx-proxy.nginx"
|
||||||
|
|
||||||
|
nginx-proxy-dockergen:
|
||||||
|
image: nginxproxy/docker-gen
|
||||||
|
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
- ../../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
|
||||||
|
- nginx_conf:/etc/nginx/conf.d
|
||||||
|
networks:
|
||||||
|
- private
|
||||||
|
|
||||||
|
web:
|
||||||
|
image: web
|
||||||
|
container_name: whoami2
|
||||||
|
expose:
|
||||||
|
- "80"
|
||||||
|
environment:
|
||||||
|
WEB_PORTS: "80"
|
||||||
|
VIRTUAL_HOST: whoami2.nginx.container.docker
|
||||||
|
networks:
|
||||||
|
- proxy
|
27
test/test_dockergen/test_dockergen_network_segregation.py
Normal file
27
test/test_dockergen/test_dockergen_network_segregation.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import docker
|
||||||
|
import pytest
|
||||||
|
from packaging.version import Version
|
||||||
|
|
||||||
|
|
||||||
|
raw_version = docker.from_env().version()["Version"]
|
||||||
|
pytestmark = pytest.mark.skipif(
|
||||||
|
Version(raw_version) < Version("1.13"),
|
||||||
|
reason="Docker compose syntax v3 requires docker engine v1.13 or later (got {raw_version})"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unknown_virtual_host_is_503(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://unknown.nginx.container.docker/")
|
||||||
|
assert r.status_code == 503
|
||||||
|
|
||||||
|
|
||||||
|
def test_forwards_to_whoami(docker_compose, nginxproxy):
|
||||||
|
r = nginxproxy.get("http://whoami2.nginx.container.docker/")
|
||||||
|
assert r.status_code == 200
|
||||||
|
whoami_container = docker_compose.containers.get("whoami2")
|
||||||
|
assert r.text == f"I'm {whoami_container.id[:12]}\n"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import doctest
|
||||||
|
doctest.testmod()
|
Reference in New Issue
Block a user