diff --git a/README.md b/README.md index 6ff07f0..d6a8aa8 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,12 @@ Finally, start your containers with `VIRTUAL_HOST` environment variables. docker run -e VIRTUAL_HOST=foo.bar.com ... ``` +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 -d -p 80:80 --name nginx -l "com.github.nginx-proxy.nginx-proxy.nginx" -v /tmp/nginx:/etc/nginx/conf.d -t nginx +``` + ### SSL Support using an ACME CA [acme-companion](https://github.com/nginx-proxy/acme-companion) is a lightweight companion container for the nginx-proxy. It allows the automated creation/renewal of SSL certificates using the ACME protocol. diff --git a/nginx.tmpl b/nginx.tmpl index f830fd2..cc0b0c1 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -11,6 +11,7 @@ {{- $_ := set $globals "Env" $.Env }} {{- $_ := set $globals "Docker" $.Docker }} {{- $_ := set $globals "CurrentContainer" (where $globals.containers "ID" $globals.Docker.CurrentContainerID | first) }} +{{- $_ := set $globals "NginxContainer" (whereLabelExists $globals.containers "com.github.nginx-proxy.nginx-proxy.nginx" | first) }} {{- $_ := set $globals "default_cert_ok" (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} {{- $_ := set $globals "external_http_port" (coalesce $globals.Env.HTTP_PORT "80") }} {{- $_ := set $globals "external_https_port" (coalesce $globals.Env.HTTPS_PORT "443") }} @@ -22,14 +23,21 @@ {{- $_ := set $globals "ssl_policy" (or ($globals.Env.SSL_POLICY) "Mozilla-Intermediate") }} {{- $_ := set $globals "vhosts" (dict) }} {{- $_ := set $globals "networks" (dict) }} -# Networks available to the container running docker-gen (which are assumed to +# Networks available to the container labeled "com.github.nginx-proxy.nginx-proxy.nginx" 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 * . For more context * see . */}} -{{- if $globals.CurrentContainer }} +{{- if $globals.NginxContainer }} + {{- range sortObjectsByKeysAsc $globals.NginxContainer.Networks "Name" }} + {{- $_ := set $globals.networks .Name . }} +# {{ .Name }} + {{- else }} +# (none) + {{- end }} +{{- else if $globals.CurrentContainer }} {{- range sortObjectsByKeysAsc $globals.CurrentContainer.Networks "Name" }} {{- $_ := set $globals.networks .Name . }} # {{ .Name }} @@ -74,11 +82,21 @@ {{- $ip = "127.0.0.1" }} {{- continue }} {{- end }} - {{- range sortObjectsByKeysAsc $.globals.CurrentContainer.Networks "Name" }} - {{- if and . .Gateway }} + {{- if $.globals.NginxContainer }} + {{- range sortObjectsByKeysAsc $.globals.NginxContainer.Networks "Name" }} + {{- if and . .Gateway }} # container is in host network mode, using {{ .Name }} gateway IP - {{- $ip = .Gateway }} - {{- break }} + {{- $ip = .Gateway }} + {{- break }} + {{- end }} + {{- end }} + {{- else }} + {{- range sortObjectsByKeysAsc $.globals.CurrentContainer.Networks "Name" }} + {{- if and . .Gateway }} + # container is in host network mode, using {{ .Name }} gateway IP + {{- $ip = .Gateway }} + {{- break }} + {{- end }} {{- end }} {{- end }} {{- if $ip }} diff --git a/test/test_dockergen/test_dockergen_network_segregation_v2.py b/test/test_dockergen/test_dockergen_network_segregation_v2.py new file mode 100644 index 0000000..dbb15d4 --- /dev/null +++ b/test/test_dockergen/test_dockergen_network_segregation_v2.py @@ -0,0 +1,10 @@ +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://whoami.nginx.container.docker/") + assert r.status_code == 200 + whoami_container = docker_compose.containers.get("whoami") + assert r.text == f"I'm {whoami_container.id[:12]}\n" diff --git a/test/test_dockergen/test_dockergen_network_segregation_v2.yml b/test/test_dockergen/test_dockergen_network_segregation_v2.yml new file mode 100644 index 0000000..949e282 --- /dev/null +++ b/test/test_dockergen/test_dockergen_network_segregation_v2.yml @@ -0,0 +1,38 @@ +version: '2' + +services: + nginx: + image: nginx + container_name: nginx + volumes: + - "/etc/nginx/conf.d" + labels: + - "com.github.nginx-proxy.nginx-proxy.nginx" + networks: + - proxy + + dockergen: + image: nginxproxy/docker-gen + command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf + volumes_from: + - nginx + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ../../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl + networks: + - internal + + web: + image: web + container_name: whoami + expose: + - "80" + environment: + WEB_PORTS: "80" + VIRTUAL_HOST: "whoami.nginx.container.docker" + networks: + - proxy + +networks: + proxy: + internal: diff --git a/test/test_dockergen/test_dockergen_network_segregation_v3.py b/test/test_dockergen/test_dockergen_network_segregation_v3.py new file mode 100644 index 0000000..b696e6c --- /dev/null +++ b/test/test_dockergen/test_dockergen_network_segregation_v3.py @@ -0,0 +1,27 @@ +import docker +import pytest +from distutils.version import LooseVersion + + +raw_version = docker.from_env().version()["Version"] +pytestmark = pytest.mark.skipif( + LooseVersion(raw_version) < LooseVersion("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://whoami.nginx.container.docker/") + assert r.status_code == 200 + whoami_container = docker_compose.containers.get("whoami") + assert r.text == f"I'm {whoami_container.id[:12]}\n" + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/test/test_dockergen/test_dockergen_network_segregation_v3.yml b/test/test_dockergen/test_dockergen_network_segregation_v3.yml new file mode 100644 index 0000000..c873c31 --- /dev/null +++ b/test/test_dockergen/test_dockergen_network_segregation_v3.yml @@ -0,0 +1,40 @@ +version: '3' + +services: + nginx: + image: nginx + container_name: nginx + volumes: + - "nginx_conf:/etc/nginx/conf.d" + labels: + - "com.github.nginx-proxy.nginx-proxy.nginx" + networks: + - 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: + - internal + + web: + image: web + container_name: whoami + expose: + - "80" + environment: + WEB_PORTS: "80" + VIRTUAL_HOST: "whoami.nginx.container.docker" + networks: + - proxy + +networks: + proxy: + internal: + +volumes: + nginx_conf: {}