Unable to loopback to host ip using docker-compose.yml file on Windows Sever 2019

Viewed 570

I am using Windows Server 2019 with Containers and Hyper-V features enabled. Also, I made sure that Windows support for Linux containers is installed on the machine. I need to use docker-compose.yml file to bring up the docker containers (web APIs) but I want the port exposed from the container to be accessible only on the host machine.

Below is the sample docker-compose.yml that I am using with loopback to 127.0.0.1.

webapi:
    image: webapi
    build:
      context: .
      dockerfile: webapi/Dockerfile
    container_name: webapi
    restart: always
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443
    ports:
      # Allow access to web APIs only on this local machine and on secure port.
      - "127.0.0.1:5443:443"

This solution works fine on Windows 10 machine with Docker Desktop installed but doesn't work on Windows Server 2019 with Docker EE installed. I get the below error where webapi is a linux image:

ERROR: for webapi Cannot start service webapi: failed to create endpoint webapi on network containers_default: Windows does not support host IP addresses in NAT settings ERROR: Encountered errors while bringing up the project.

My Windows Server 2019 docker configuration looks like this:

PS C:\Users\xyz> docker version
Client: Mirantis Container Runtime
 Version:           20.10.5
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        105e9a6
 Built:             05/17/2021 16:36:02
 OS/Arch:           windows/amd64
 Context:           default
 Experimental:      true

Server: Mirantis Container Runtime
 Engine:
  Version:          20.10.5
  API version:      1.41 (minimum version 1.24)
  Go version:       go1.13.15
  Git commit:       1a7d997053
  Built:            05/17/2021 16:34:40
  OS/Arch:          windows/amd64
  Experimental:     true

PS C:\Users\xyz> docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker Application (Docker Inc., v0.8.0)
  cluster: Manage Mirantis Container Cloud clusters (Mirantis Inc., v1.9.0)
  registry: Manage Docker registries (Docker Inc., 0.1.0)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 5
 Server Version: 20.10.5
 Storage Driver: windowsfilter (windows) lcow (linux)
  Windows:
  LCOW:
 Logging Driver: json-file
 Plugins:
  Volume: local
  Network: ics internal l2bridge l2tunnel nat null overlay private transparent
  Log: awslogs etwlogs fluentd gcplogs gelf json-file local logentries splunk syslog
 Swarm: inactive
 Default Isolation: process
 Kernel Version: 10.0 17763 (17763.1.amd64fre.rs5_release.180914-1434)
 Operating System: Windows Server 2019 Datacenter Version 1809 (OS Build 17763.1999)
 OSType: windows
 Architecture: x86_64
 CPUs: 4
 Total Memory: 16GiB

Any help would be greatly appreciated.

1 Answers

After spending a fair amount of time I didn't find a way to fix the Windows does not support host IP addresses in NAT settings error nor using any other network / driver (bridge, host, etc). However, I found a workaround to make the port exposed only on the local machine by configuring the Kestrel web server of the web app (container) using the "AllowedHosts" parameter in the appsettings.json. I set the parameter value like below:

    {
      // allow the web apis to be accessible only on host machine as a security measure.
      // allow access only if the host in the URL matches the values mentioned in the list.
      "AllowedHosts": "localhost;127.0.0.1",
      "Serilog": {
        "Using": [],
        "MinimumLevel": {
          "Default": "Debug",
          "Override": {
            "Microsoft": "Warning",
            "System": "Warning"
          }
        },
    ...
    }

All this does is to check if the host in the URL is either localhost or 127.0.0.1 which is similar to loopback.

You can also override this parameter by passing the "AllowedHosts" parameter in the environment variable in the yml file like below:

webapi:
    image: webapi
    build:
      context: .
      dockerfile: webapi/Dockerfile
    container_name: webapi
    restart: always
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443
      - AllowedHosts=*
    ports:
      # Allow access to web APIs only on this local machine and on secure port.
      - "5443:443"

Please note that AllowedHosts is not used here for safe-listing the IPs to accept the connections from as it works on the basis of the target host mentioned in the URL.

Related