Customizing Containers - artisticcheese/artisticcheesecontainer GitHub Wiki

Customizing container network

Default container network is automatically created during docker installation in 172.16.0.0/12 network. You can inspect your specific network config by executing Get-ContainerNet cmdlet.

PS C:\Users\Administrator> get-containernet

Id              Name            Driver
--              ----            ------
2c5a8847d03d... nat             nat
3cc8bbc684ad... none            null

If you don't specify which network you would like your new containers to be launched on then they will be launched on nat network. Another popular option to host containers to allow them to access physical network in bridge mode. With this setup they will share physical network adapter on your container host and will receive DHCP from the same DHCP server as your physical network adapter or you can assign IP address in the same space as container host adapter. You can create bridged network with following command where bridged is customizable name for that network

docker network create -d transparent bridged

Once it's created you can verify docker can see by executing

PS D:\docker> get-containernet
Id              Name            Driver
--              ----            ------
f03a37d97cfc... nat             nat
387eae7a871b... Bridged         transparent
22f23c78c8ea... none            null

To launch your container and attach to bridge you can use following code

$hostConfig = [Docker.DotNet.Models.HostConfig]::new()
$hostConfig.NetworkMode = "bridged"
Run-ContainerImage -ImageIdOrName "microsoft/iis:latest" -Detach -HostConfiguration $hostConfig -Name iis

Login to newly launched container and in fact verify that it get's IP address from physical network

PS C:\Users\Administrator> Enter-PSSession -ContainerId (get-container iis).ID -RunAsAdministrator
[b8833a73a5b3...]: PS C:\Users\ContainerAdministrator\Documents> ipconfig

Windows IP Configuration


Ethernet adapter vEthernet (Container NIC 250ebc9a):

   Connection-specific DNS Suffix  . : artisticcheese.com
   Link-local IPv6 Address . . . . . : fe80::d164:8278:bf77:1c20%37
   IPv4 Address. . . . . . . . . . . : 192.168.1.191
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.1.1

One of advantages of this approach is that you don't rely on docker to reverse proxy connections to container and you can directly access services on container via it's direct IP address

PS C:\Users\Administrator> Invoke-WebRequest 192.168.1.191 | select statuscode

StatusCode
----------
       200

For nat network type you have to create port forwarding when you launch container for container endpoint to be accessible from outside of container host.

Via docker powershell module this is done in following steps. This maps Container Host port 8080 to port 80 on container.

Import-module docker
$config = [Docker.DotNet.Models.Config]::new()
($config.ExposedPorts  = [System.Collections.Generic.Dictionary[string,object]]::new()).Add("80/tcp", $null)
$hostConfig = [Docker.DotNet.Models.HostConfig]::new()
$pb = new-object Docker.DotNet.Models.PortBinding
$pb.HostPort = "8080"
$hostConfig.PortBindings = [System.Collections.Generic.Dictionary[string, System.Collections.Generic.iList[Docker.DotNet.Models.PortBinding]]]::new()
$hostConfig.PortBindings.Add("80/tcp",[System.Collections.Generic.List[Docker.DotNet.Models.PortBinding]]::new([Docker.DotNet.Models.PortBinding[]]@($pb)))
Run-ContainerImage -ImageIdOrName "microsoft/iis:latest" -Configuration $config -Detach -HostConfiguration $hostConfig -Name $pb.HostPort  

To verify your port mappings you can use docker ps command which will output conveniently port mappings from container host into container

PS C:\Windows\system32> docker ps
CONTAINER ID        IMAGE                  COMMAND                   CREATED             STATUS              PORTS                   NAMES
32561bf36d76        microsoft/iis:latest   "C:\\ServiceMonitor..."   7 seconds ago       Up 3 seconds        0.0.0.0:8080->80/tcp    8080