On the Adafruit Discord server, user @madboger asked a question regarding Docker. Their question was:
Cool! One quick question on my own project: if I'm running a web service inside Docker, how does the TCP port appear on the host? I assume there's some forwarding configuration somewhere that describes the mapping?
Here is [my response and brief explanation][Response], in simplified terms, to cover the majority of the circumstances and avoid the more complex situations...
That's correct @madbodger, there is a mapping. In reality, the way I see it, there's 2 parts.
The first is that in the Dockerfile, you specify which port(s) you want to be accessible from outside the container. So you'd specify port 80 for HTTP.
The second part is when you're using the container, either from a docker run ...
, from another Dockerfile, in a Kubernetes (K8s) cluster or elsewhere, you specify which "outside" port you want to use to "tunnel" into the inside port.
Example (all this assumes running locally, I can cover running in a hosted/external separately if anybody wants)
I create a PHP-based web application that runs completely inside a container, and that's accessed from a browser. So in my app's Dockerfile, I would add a EXPOSE 80
(or EXPOSE 80/TCP
if I want to explicitly specify TCP or UDP) statement, so that it can accept incoming connections on port 80.
From my own computer, I would run an instance of the container with a command like docker run --rm -d --name MyPHPAppContainer -p 4321:80 MyPHPApp
. The key part here, is the -p 4321:80
. That says "When the host gets a connection on port 4321, forward that request to port 80 of the container named "MyPHPAppContainer", which is an instance of the "MyPHPApp" definition.
So, as a real-world example, if you wanted to try it out, after installing docker, run this command: docker run --rm --name Apache -d -p 4321:80 httpd
This will run the base httpd image, which is the Apache HTTPD server, and expose its internal port 80 to the host's (your computer) port 4321. After the command runs, you're returned to the command prompt, but you can check that the image is running by using the docker container ls
command, which in essence, runs an ls
(list) command on all running docker containers. The output should look similar to this:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
253ce121201d httpd "httpd-foreground" 2 minutes ago Up 2 minutes 0.0.0.0:4321->80/tcp Apache
That "PORTS" column is the one that interests us in this case. Then, to make sure that port forwarding is working, open a browser to "http://localhost:4321/". If it went as expected, you'll notice "It works!"