I have several ASP.NET Core services defined in docker-compose
. I need to be able to expose port in the host
network (I use linux containers on Docker for Windows 18.03.0-ce).
Sample:
- Services C1 and C2 are running in containers.
- Service H3 is running directly in the host, not in container.
- All services (C1, C2 and H3) must be accesible to each other.
I don’t know how to setup networking for services C1 and C2 in docker-compose
. I tried this:
version: '3' services: c1: image: <some image name> build: context: . dockerfile: <path to dockerfile> environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://localhost:9084 ports: - "9084:9084" network_mode: "host" c2: image: <some image name> build: context: . dockerfile: <path to dockerfile> environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://localhost:9085 ports: - "9085:9085" network_mode: "host"
I see this in the console when containers are started:
Hosting environment: Development Content root path: /app Now listening on: http://localhost:9085 Application started. Press Ctrl+C to shut down.
But I cannot connect them from the host. netstat -an
doesn’t show these ports, telnet localhost 9084
fails.
This is output from docker inspect
for that container:
"NetworkSettings": { "Bridge": "", "SandboxID": "df480d4d68cb109dc6b85f689f8b210a9f74e650c48a343cdd3d11eb3d10bec7", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/default", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": { "host": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "324d836f54fa685d56b416f01a18e3e75f88d4516dafac43bb1a4ff760a2b67a", "EndpointID": "9212f6a01e142ef9fb71116c9fe03c37567c60ed8a2add91fe28bf0bd6de001a", "Gateway": "", "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "", "DriverOpts": null } } }
When I remove network_mode: "host"
configuration from docker-compose
(network is then bridge
as default), I get this message form the application:
warn: Microsoft.AspNetCore.Server.Kestrel[0] Unable to bind to http://localhost:9084 on the IPv6 loopback interface: 'Error -99 EADDRNOTAVAIL address not available'.
Can you help me to setup the network configuration?
Advertisement
Answer
I found a solution for my problem:
- I do not set any network in
docker-compose
(the generated *_default withbridge
driver is used) – removednetwork_mode
. - I removed
ASPNETCORE_URLS
ENV variable indocker-compose
. - APS.NET Core applications use port 80 (inside container).
- Port 80 is exposed (for example) as 9084 to be accessible from the host.
- Application is configured to use (for example)
localhost:9085
. docker-compose
uses environment variable to override the endpoint tohost.docker.internal.9085
.
Now, all services running in containers use host.docker.internal
and some port
to connect to some other service, so these services can connect other services running in a container or directly in the host.
Services running in the host use localhost
and some port, so they can connect other services running in the host or in the container.
This is sample of docker-compose
file:
version: '3' services: c1: image: <some image name> build: context: . dockerfile: <path to dockerfile> environment: - ASPNETCORE_ENVIRONMENT=Development env_file: - docker-compose.override.env ports: - "9084:80" c2: image: <some image name> build: context: . dockerfile: <path to dockerfile> environment: - ASPNETCORE_ENVIRONMENT=Development env_file: - docker-compose.override.env ports: - "9085:80"
Sample of docker-compose.override.env
file:
ApiOptions__DomainModelApiBaseUrl=http://host.docker.internal:9081/api ApiOptions__SearchApiBaseUrl=http://host.docker.internal:9088/api
Now I am able to run the same service in container or from Visual Studio and debug it.