Container Port Mapping
By the end of this exercise, you should be able to:
- Forward traffic from a port on the docker host to a port inside a container's network namespace
- Define ports to automatically expose in a Dockerfile
Port Mapping at Runtime
Run an IIS container with no special port mappings:
PS: node-1 Administrator> docker container run -d microsoft/iisIIS stands up a landing page at
http://<IP>:80; try to visit this at your host's public IP, and it won't be visible; no external traffic can make it past the Windows NAT's firewall to the container running IIS.Now run an IIS container and map port 80 on the container to port 5000 on your host using the
-pflag:PS: node-1 Administrator> docker container run -d -p 5000:80 --name iis microsoft/iisNote that the syntax is:
-p [host-port]:[container-port].Verify the port mappings with the
docker container portcommand:PS: node-1 Administrator> docker container port iisOpen a browser window and visit your IIS landing page at
<host ip>:5000; you should see the default IIS landing page. Your browser's network request to port 5000 in the host network namespace has been forwarded on to the container's network namespace at port 80.List your network address translation rules:
PS: node-1 Administrator> Get-NetNatStaticMapping StaticMappingID : 0 NatName : H3acfc61d-0d8e-438c-8857-9c2b742707bf Protocol : TCP RemoteExternalIPAddressPrefix : 0.0.0.0/0 ExternalIPAddress : 0.0.0.0 ExternalPort : 5000 InternalIPAddress : 172.20.142.213 InternalPort : 80 InternalRoutingDomainId : {00000000-0000-0000-0000-000000000000} Active : TrueThere should be a rule matching your container IP, internal and external port, such as above.
Exposing Ports from the Dockerfile
In addition to manual port mapping, we can expose some ports in a Dockerfile for automatic port mapping on container startup. In a fresh directory
portdemo, create a Dockerfile:FROM microsoft/iis EXPOSE 80Build your image as
my_iis:PS: node-1 portdemo> docker image build -t my_iis .Use the
-Pflag when running to map all ports mentioned in theEXPOSEdirective:PS: node-1 portdemo> docker container run -d -P my_iisUse
docker container lsordocker container portto find out what host ports were used, and visit your IIS landing page in a browser at<node-1 public IP>:<port>.Clean up your containers:
PS: node-1 portdemo> docker container rm -f $(docker container ls -aq)
Conclusion
In this exercise, we saw how to explicitly map ports from our container's network stack onto ports of our host at runtime with the -p option to docker container run, or more flexibly in our Dockerfile with EXPOSE, which will result in the listed ports inside our container being mapped to random available ports on our host.