Access Docker-hosted apps from the Docker host
Accessing Docker-hosted apps from the Docker host
Docker containers attached to a MACVLAN network (only) can not be accessed by the Docker host.
I use a MACVLAN network for a few of my Docker containers so they appear as a separate network device to other devices on the network.
docker network ls | egrep '^NETWORK | mynet192'
NETWORK ID NAME DRIVER SCOPE
52875db418f4 mynet192 macvlan local
However, due to a kernel restriction, no MACVLAN child interface (Docker container) is allowed to communicate with the parent interface (Docker host).
The end result is that the Docker host can't use the service(s) running in Docker containers attached to the MACVLAN network
Basic container config
For example, using a simple nginx container definition:
version: "3.8"
services:
nginx:
image: nginx:latest
restart: unless-stopped
container_name: test123
ports:
- 8080:80
networks:
mynet192:
ipv4_address: 192.168.1.222
networks:
mynet192:
external: true
docker ps | egrep '^CONTAINER | container_test'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef3af1a4b240 nginx:latest "/docker-entrypoint.…" 14 seconds ago Up 10 seconds container_test
No connectivity when using only the MACVLAN network
After the container is started, the Docker host can't access the nginx service.
curl -v 192.168.1.222
* Trying 192.168.1.222:80...
* connect to 192.168.1.222 port 80 failed: No route to host
* Failed to connect to 192.168.1.222 port 80 after 3064 ms: No route to host
* Closing connection 0
curl: (7) Failed to connect to 192.168.1.222 port 80 after 3064 ms: No route to host
Workaround so the Docker host can use service(s) running in Docker containers
To work around this restriction, create a Docker bridge network, and add this bridge network to the Docker container.
I want some of my containers to have a static IP assigned from this new bridge network, so I restricted the addresses Docker would hand out via DHCP to have the /24 subnet using the --ip-range switch in the network definition.
docker network create -d bridge --subnet 172.28.0.0/24 --ip-range 172.28.0.128/25 Internal
Updating the compose.yaml file to specify the Internal network in the network definition, and to add it to the container definition, with a specific static IP.
version: "3.8"
services:
nginx:
image: nginx:latest
restart: unless-stopped
container_name: container_test
ports:
- 8080:80
networks:
mynet192:
ipv4_address: 192.168.1.222
Internal:
ipv4_address: 172.28.0.222
networks:
mynet192:
external: true
Internal:
external: true
After adding the Internal network to the container, the Docker host can now access the nginx service running in the container.
curl -v 172.28.0.222
* Trying 172.28.0.222:80...
* Connected to 172.28.0.222 (172.28.0.222) port 80 (#0)
> GET / HTTP/1.1
> Host: 172.28.0.222
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.25.3
< Date: Wed, 01 Oct 2023 20:51:27 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Tue, 24 Jul 2023 13:46:47 GMT
< Connection: keep-alive
< ETag: "6537cac7-267"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 172.28.0.222 left intact