diff --git a/Makefile b/Makefile index 213a441..3a10ad4 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ update-dependencies: docker pull python:3 docker pull rancher/socat-docker:latest docker pull appropriate/curl:latest - docker pull docker:1.9 + docker pull docker:1.10 test: docker build -t jwilder/nginx-proxy:bats . diff --git a/README.md b/README.md index ed082cf..db870d8 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,20 @@ If you need to support multiple virtual hosts for a container, you can separate You can also use wildcards at the beginning and the end of host name, like `*.bar.com` or `foo.bar.*`. Or even a regular expression, which can be very useful in conjunction with a wildcard DNS service like [xip.io](http://xip.io), using `~^foo\.bar\..*\.xip\.io` will match `foo.bar.127.0.0.1.xip.io`, `foo.bar.10.0.2.2.xip.io` and all other given IPs. More information about this topic can be found in the nginx documentation about [`server_names`](http://nginx.org/en/docs/http/server_names.html). +### 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`. + +If you want your `nginx-proxy` container to be attached to a different network, you must pass the `--net=my-network` option in your `docker create` or `docker run` command. At the time of this writing, only a single network can be specified at container creation time. To attach to other networks, you can use the `docker network connect` command after your container is created: + +```console +$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro \ + --name my-nginx-proxy --net my-network jwilder/nginx-proxy +$ docker network connect my-other-network my-nginx-proxy +``` + +In this example, the `my-nginx-proxy` container will be connected to `my-network` and `my-other-network` and will be able to proxy to other containers attached to those networks. + ### SSL Backends If you would like to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container. diff --git a/circle.yml b/circle.yml index e0ecf4d..761684f 100644 --- a/circle.yml +++ b/circle.yml @@ -1,7 +1,6 @@ machine: pre: - - sudo curl -L -o /usr/bin/docker 'https://s3-external-1.amazonaws.com/circle-downloads/docker-1.9.1-circleci' - - sudo chmod 0755 /usr/bin/docker + - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 services: - docker diff --git a/nginx.tmpl b/nginx.tmpl index 255cc35..343a801 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,3 +1,5 @@ +{{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }} + {{ define "upstream" }} {{ if .Address }} {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} @@ -5,13 +7,13 @@ # {{ .Container.Node.Name }}/{{ .Container.Name }} server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }}; {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} - {{ else }} + {{ else if .Network }} # {{ .Container.Name }} - server {{ .Address.IP }}:{{ .Address.Port }}; + server {{ .Network.IP }}:{{ .Address.Port }}; {{ end }} - {{ else }} + {{ else if .Network }} # {{ .Container.Name }} - server {{ .Container.IP }} down; + server {{ .Network.IP }} down; {{ end }} {{ end }} @@ -75,15 +77,24 @@ server { 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) }} + + {{ range $knownNetwork := $CurrentContainer.Networks }} + {{ range $containerNetwork := $container.Networks }} + {{ if eq $knownNetwork.Name $containerNetwork.Name }} + ## Can be connect with "{{ $containerNetwork.Name }}" network + + {{/* If only 1 port exposed, use that */}} + {{ if eq $addrLen 1 }} + {{ $address := index $container.Addresses 0 }} + {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} + {{/* 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 "Network" $containerNetwork) }} + {{ end }} + {{ end }} + {{ end }} {{ end }} {{ end }} } diff --git a/test/docker.bats b/test/docker.bats index 43be758..f90d270 100644 --- a/test/docker.bats +++ b/test/docker.bats @@ -54,7 +54,7 @@ load test_helpers @test "[$TEST_FILE] separated containers (nginx + docker-gen + nginx.tmpl)" { docker_clean bats-nginx docker_clean bats-docker-gen - + # GIVEN a simple nginx container run docker run -d \ --label bats-type="nginx" \ @@ -73,6 +73,7 @@ load test_helpers -v /var/run/docker.sock:/tmp/docker.sock:ro \ -v $BATS_TEST_DIRNAME/../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \ --volumes-from bats-nginx \ + --expose 80 \ jwilder/docker-gen:0.7.0 \ -notify-sighup bats-nginx \ -watch \ @@ -91,7 +92,7 @@ load test_helpers docker logs bats-docker-gen false } >&2 - + # THEN assert_nginxproxy_behaves bats-nginx } @@ -120,4 +121,3 @@ function assert_nginxproxy_behaves { run curl_container $container /data --header "Host: webFOO.bats" --head assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' } - diff --git a/test/lib/docker_helpers.bash b/test/lib/docker_helpers.bash index 1735506..221234e 100644 --- a/test/lib/docker_helpers.bash +++ b/test/lib/docker_helpers.bash @@ -62,5 +62,5 @@ function docker_tcp { --expose 2375 \ -v /var/run/docker.sock:/var/run/docker.sock \ rancher/socat-docker - docker run --label bats-type="docker" --link "$container_name:docker" docker:1.9 version + docker run --label bats-type="docker" --link "$container_name:docker" docker:1.10 version }