
$ sudo lsof -i -P | grep LISTEN | grep :8080Ĭom.docke. You can pinpoint this process with lsof: $ docker run -d -p 8080:80 -name nginx-1 nginx When you start a container that publishes a port, a proxy process on the host (e.g, on macOS) opens a real socket using the specified IP address and port. To cut a long story short, in the case of Docker Desktop, it's a combination of user space-based and traditional iptables-based port forwarding. Evidently, it's not routable from the host system (macOS, in my case). Therefore, the above 172.17.0.3 address is an address from a bridge network that exists only inside that virtual machine.

DOCKER CONTAINER PORT MAPPING FOR MAC
So, Docker Desktop for Mac (and likely for Windows and Linux as well) sneakily starts a full-blown virtual machine running a custom Linux distro with pre-installed Docker Engine. Docker containers require a Linux kernel. Being able to access that IP address allows you to call any services running inside of the container (assuming they listen on the container's public interface).įor instance, with Docker Engine on Linux (not to be confused with Docker Desktop that also supports Linux since May 2022), you can create an nginx container and curl it from the host: $ docker run -d -name nginx-1 nginxĭocker inspect -f '' nginx-1 Normally, a container has its own network stack and IP address.
DOCKER CONTAINER PORT MAPPING HOW TO
So, port forwarding or, as it's also called, port mapping is just a fancy way to say that data addressed to one socket is redirected to another by an intermediary (for instance, by a network router or a proxy process).īecause I think that understanding the idea behind port forwarding and the most common ways to implement it is vital for the in-depth discussion of why and how to publish container ports. Sockets are meant to represent the participants of a network data exchange. When we say port we usually refer to a certain socket address defined by a pair of IP address and port number.

I'll also take a look under the hood of different "single-host" container runtimes (Docker Engine, Docker Desktop, containerd, nerdclt, and Lima) to compare the port publishing implementations and capabilities.Īs always, the ultimate goal is to gain a deeper understanding of the technology and get closer to becoming a power user of containers. In this article, I'll try to connect the dots between port publishing, the term apparently coined by Docker, and a more traditional networking technique called port forwarding. Easy-peasy!īut have you ever wondered what actually happens when you ask Docker to publish a port? The next thing you do is docker run -p 8080:80 app and then open localhost:8080 in the browser. A typical need for publishing arises like this: you're developing a web app, locally but in a container, and you want to test it using your laptop's browser. Using this as the nginx.If you're dealing with containers regularly, you've probably published ports many, many times already. The new docker-compose will look something like this - version: '3'Īnd the custom-nginx image should be built like so - FROM nginx:1.17-alpine You can achieve what you are trying to do by adding another container to the docker-compose.yaml, which will act as a reverse proxy in front of the barfoo container. The foobar container, however, is hitting the container port directly, which is listening on port 80 alone. When you execute curl from your terminal, you are hitting the local port 8002 of your computer, which is forwarding port 80 of your container. Then foobar would connect to barfoo using service name and port barfoo:80 If that's really what you want, a better alternative would be to use docker stack.Īnd your services would be docker swarm services:ĭocker deploy -compose-file path_to_compose_file Hostname and both can use port 80 directly

Where in production there is no port needed since they use a different The reason why is that I want to simulate a production like situation, foobar:īut then foobar would need to connect using localhost:8002 You can add network_mode: host to barfoo and foobar. However barfoo listens on port 80 inside the container and not on 8002. So when you run curl from foobar container you try to connect to service barfoo to port 8002.

But that's probably not what you want.īarfoo is service name registered in internal docker dns accessible only by the services ( foobar) within the same docker network created when you run docker-compose up Simple solution is to map host port 8002 to barfoo port 8002. How can I make curl work from the foobar-container, without making changes to the docker file?
