Skip to content

Commit

Permalink
Merge pull request #2222 from rot169/support-hostnet-containers
Browse files Browse the repository at this point in the history
Support containers running --net=host (#1537)
  • Loading branch information
buchdag committed Jun 7, 2023
2 parents a81d03c + e22caf7 commit c1a2b31
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ 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.

### Host networking

`nginx-proxy` is compatible with containers using Docker's [host networking](https://docs.docker.com/network/host/), both with the proxy connected to one or more [bridge network](https://docs.docker.com/network/bridge/) (default or user created) or running in host network mode itself.

Proxyed containers running in host network mode **must** use the [`VIRTUAL_PORT](#virtual-ports) environment variable, as this is the only way for `nginx-proxy` to get the correct port (or a port at all) for those containers.

### Custom external HTTP/HTTPS ports

If you want to use `nginx-proxy` with different external ports that the default ones of `80` for `HTTP` traffic and `443` for `HTTPS` traffic, you'll have to use the environment variable(s) `HTTP_PORT` and/or `HTTPS_PORT` in addition to the changes to the Docker port mapping. If you change the `HTTPS` port, the redirect for `HTTPS` traffic will also be configured to redirect to the custom port. Typical usage, here with the custom ports `1080` and `10443`:
Expand Down
18 changes: 18 additions & 0 deletions nginx.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,24 @@
# {{ .Name }} (ignored)
{{- continue }}
{{- end }}
{{- if eq .Name "host" }}
{{- /* Handle containers in host nework mode */}}
{{- if (index $.globals.networks "host") }}
# both container and proxy are in host network mode, using localhost IP
{{- $ip = "127.0.0.1" }}
{{- continue }}
{{- end }}
{{- range sortObjectsByKeysAsc $.globals.CurrentContainer.Networks "Name" }}
{{- if and . .Gateway }}
# container is in host network mode, using {{ .Name }} gateway IP
{{- $ip = .Gateway }}
{{- break }}
{{- end }}
{{- end }}
{{- if $ip }}
{{- continue }}
{{- end }}
{{- end }}
{{- if and (not (index $.globals.networks .Name)) (not $.globals.networks.host) }}
# {{ .Name }} (unreachable)
{{- continue }}
Expand Down
8 changes: 8 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ def container_ip(container: Container):
net_info = container.attrs["NetworkSettings"]["Networks"]
if "bridge" in net_info:
return net_info["bridge"]["IPAddress"]

# container is running in host network mode
if "host" in net_info:
return "127.0.0.1"

# not default bridge network, fallback on first network defined
network_name = list(net_info.keys())[0]
Expand All @@ -173,6 +177,10 @@ def container_ipv6(container):
net_info = container.attrs["NetworkSettings"]["Networks"]
if "bridge" in net_info:
return net_info["bridge"]["GlobalIPv6Address"]

# container is running in host network mode
if "host" in net_info:
return "::1"

# not default bridge network, fallback on first network defined
network_name = list(net_info.keys())[0]
Expand Down
13 changes: 13 additions & 0 deletions test/test_host-network-mode/test_host-network-mode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest


def test_forwards_to_bridge_network_container(docker_compose, nginxproxy):
r = nginxproxy.get("http://bridge-network.nginx-proxy.tld/port")
assert r.status_code == 200
assert r.text == "answer from port 80\n"


def test_forwards_to_host_network_container(docker_compose, nginxproxy):
r = nginxproxy.get("http://host-network.nginx-proxy.tld/port")
assert r.status_code == 200
assert r.text == "answer from port 8080\n"
31 changes: 31 additions & 0 deletions test/test_host-network-mode/test_host-network-mode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: "2"

networks:
net1:
internal: true
net2:

services:
bridge-network:
image: web
environment:
WEB_PORTS: "80"
VIRTUAL_HOST: "bridge-network.nginx-proxy.tld"
networks:
- net2

host-network:
image: web
environment:
WEB_PORTS: "8080"
VIRTUAL_HOST: "host-network.nginx-proxy.tld"
VIRTUAL_PORT: "8080"
network_mode: host

sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
- net1
- net2
13 changes: 13 additions & 0 deletions test/test_host-network-mode/test_proxy-host-network-mode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest


def test_forwards_to_host_network_container_1(docker_compose, nginxproxy):
r = nginxproxy.get("http://host-network-1.nginx-proxy.tld:8888/port")
assert r.status_code == 200
assert r.text == "answer from port 8080\n"


def test_forwards_to_host_network_container_2(docker_compose, nginxproxy):
r = nginxproxy.get("http://host-network-2.nginx-proxy.tld:8888/port")
assert r.status_code == 200
assert r.text == "answer from port 8181\n"
26 changes: 26 additions & 0 deletions test/test_host-network-mode/test_proxy-host-network-mode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: "2"

services:
host-network-1:
image: web
environment:
WEB_PORTS: "8080"
VIRTUAL_HOST: "host-network-1.nginx-proxy.tld"
VIRTUAL_PORT: "8080"
network_mode: host

host-network-2:
image: web
environment:
WEB_PORTS: "8181"
VIRTUAL_HOST: "host-network-2.nginx-proxy.tld"
VIRTUAL_PORT: "8181"
network_mode: host

sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTP_PORT: 8888
network_mode: host

0 comments on commit c1a2b31

Please sign in to comment.