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 withbridgedriver is used) – removednetwork_mode. - I removed
ASPNETCORE_URLSENV 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-composeuses 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.