Let's cut the fluff. Here is exactly what you need to know about this concept to survive in a real production environment.
1The EXPOSE Illusion
Look, if you've ever dealt with this in production, you know exactly what the problem is. There is a massive point of confusion for Docker beginners. You see the instruction EXPOSE 8080 inside a Dockerfile. You assume this means the container is magically available to the public internet on port 8080. This is a dangerous illusion. The EXPOSE instruction does absolutely nothing to your network. It is purely documentation. It is a sticky note left by the developer saying, 'Hey, the application inside is listening on port 8080, you might want to open that later.' This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy to a cluster, this is the mechanic that prevents catastrophic failure.
FROM node:18
# ... setup app ...
# This does NOT open the port to the internet!
# It is just documentation for the next developer.
EXPOSE 8080
Status: OK
Success: Operation completed.
2Port Publishing (-p)
Look, if you've ever dealt with this in production, you know exactly what the problem is. To actually route traffic from the Host machine (your laptop) into the Container, you must 'Publish' the port. You do this at runtime using the -p flag: docker run -p 8080:80 nginx. The syntax is always HostPort:ContainerPort. This tells the Docker Daemon to open port 8080 on your physical laptop, listen for traffic, and forcefully inject that traffic through the container's isolated network namespace into port 80. This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy to a cluster, this is the mechanic that prevents catastrophic failure.
# Open laptop port 8080, route to container port 80
> docker run -p 8080:80 nginx
# You can now visit http://localhost:8080
# and Docker bridges it to the Nginx container.
Status: OK
Success: Operation completed.
3Port Collisions
Look, if you've ever dealt with this in production, you know exactly what the problem is. A physical computer has exactly 65,535 ports. A single port can only be used by ONE application at a time. If you try to run two Nginx containers and map them both to port 80 on your laptop (docker run -p 80:80), the first one succeeds. The second one crashes instantly with an 'address already in use' error. To fix this, you map them to different Host ports: -p 8081:80 and -p 8082:80. This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy to a cluster, this is the mechanic that prevents catastrophic failure.
# Container 1 binds to Host port 80 (Success)
> docker run -p 80:80 nginx
# Container 2 tries to bind to Host port 80 (CRASH)
> docker run -p 80:80 nginx
# Error: Bind for 0.0.0.0:80 failed: port is already allocated.
Status: OK
Success: Operation completed.
