Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Docker Tip #59: Difference between Exposing and Publishing Ports

blog/cards/docker-tips-and-tricks.jpg

You can expose ports by using EXPOSE in your Dockerfile, --expose on the command line but there's also publishing ports too.

When you put EXPOSE 80 (or any port you want) in your Dockerfile that’s going to tell Docker that your container’s service can be connected to on port 80.

It doesn’t set up any networking properties. You can think of it more like a runtime configuration option that’s explicitly stated in your Dockerfile.

You can also expose a port using --expose 80 from the docker container run --expose 80 ... command, but you only need to do this if you don’t have EXPOSE defined in your Dockerfile, but depending on what you want to do, you may not need to expose anything.

Allowing Containers to Talk to Each Other Internally

Containers on the same network can talk to each other over their exposed ports without having to publish ports back to the Docker host with -p.

This is useful for services like Postgres or Redis. These are things you typically wouldn’t want accessible from the internet, but you would want them accessible to your web application containers running on the same Docker network.

If that’s the case you’ll need to use EXPOSE or --expose, but…

If you check out the official Docker images for Postgres and Redis, you’ll notice they set up EXPOSE 5432 (Postgres) and EXPOSE 6379 (Redis) in their Dockerfile already.

Allowing Containers to Talk to Each Other + the Outside World

In this case, you have a few options:

  1. You can expose a port through your Dockerfile or use --expose and then publish it with the -P flag. This will bind the exposed port to your Docker host on a random port (verified by running docker container ls).

  2. You can expose a port through your Dockerfile or use --expose and then publish it with the -p 80:80 flag. This will bind the exposed port to your Docker host on port 80, and it expects the exposed port is 80 too (adjust as necessary with HOST:CONTAINER).

  3. You can ignore exposing anything and just use -p 80:80 in which case this doubles as both exposing AND publishing the port.

What Should You Do?

I think it’s a good idea to always use EXPOSE in your Dockerfile because it explicitly states what port the service uses, and if you don’t want to publish it to your Docker host, you don’t have to worry about setting --expose so other containers can access it.

Free Intro to Docker Email Course

Over 5 days you'll get 1 email per day that includes video and text from the premium Dive Into Docker course. By the end of the 5 days you'll have hands on experience using Docker to serve a website.


Comments