1. Overview

Docker is a platform that allows us to create and run applications in isolated lightweight containers.

In this tutorial, we’ll learn to resolve the issues related to the port binding on a Docker container. This is one of the most common errors that beginners face while working with Docker. We’ll also examine the root cause of this issue, and different approaches to solving it.

2. Understanding the Problem

In Docker, the issue “address already in use” occurs when we try to expose a container port that’s already acquired on the host machine.

To resolve the issue, we first need to reproduce the problem. Let’s assume that port 8080 on the Docker host machine is already occupied. There could be multiple reasons for this, like the Tomcat server has occupied this port, or some random process is using it.

We’ll try to run a Docker container and expose the same port 8080 on the host:

$ docker run -itd -e POSTGRES_USER=baeldung -e POSTGRES_PASSWORD=baeldung
  -p 8080:5432 -v /data:/var/lib/postgresql/data --name postgresql-baeldung postgres
Unable to find image 'postgres:latest' locally
latest: Pulling from library/postgres
42c077c10790: Already exists 
3c2843bc3122: Pull complete 
...
ad029fbc8984: Pull complete 
Digest: sha256:2d1e636f07781d4799b3f2edbff78a0a5494f24c4512cb56a83ebfd0e04ec074
Status: Downloaded newer image for postgres:latest
22e97efd420eee8ba2d77a956933d00b04784b0b04c97ffc09e127f10932dea9
docker: Error response from daemon: driver failed programming external connectivity
  on endpoint postgresql-baeldung (154f66d3ba8bee4dafba092137311c43b950c31884e199d34d2b1d301496f9b5):
  Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use.

In the above output, port 8080 has already been acquired, so we can’t run the Docker container. Since the container failed to start, we must remove it as well. Let’s take a look at the command to remove the Docker container:

$ docker rm -f  postgresql-baeldung
postgresql-baeldung

Here we successfully removed the “postgresql-baeldung” Docker container.

3. Solving the Bind Address Issue

So far, we’ve reproduced the issue and discussed the root cause of the problem. Now let’s explore the possible ways to resolve it.

3.1. Killing the Process

The Error “address already in use” occurred because some process was already running on the same port. So we can resolve the issue just by killing the process.

To stop the process, we need the process ID (PID), which we can fetch using the lsof command. The lsof command lets us know which processes open which files, so we can use this command to know the PID of the process running on a particular port. By default, the lsof package isn’t installed in Linux.

Let’s look at the command to install the lsof:

$ yum install -y  lsof

Using the above command, we successfully installed the lsof package. Now let’s see the command to get the PID of the process using the lsof command:

$ sudo lsof -i:8080
COMMAND     PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java      78812 root   66u  IPv6 0xe28ed26f1f48e597      0t0  TCP *:http-alt (LISTEN)

Note that sudo is necessary to show system processes. In the output of the above command, we can see that a Java process is already running on the 8080 port, causing the “Error bind: address already in use” issue. To resolve the issue, we need to kill this process using the kill command:

$ kill 78812

Now we can run our container without any issues:

$ docker run -itd -e POSTGRES_USER=baeldung -e POSTGRES_PASSWORD=baeldung
  -p 8080:5432 -v /data:/var/lib/postgresql/data --name postgresql-baeldung postgres
  154f66d3ba8bee4dafba092137311c43b950c31884e199d34d2b1d301496f9b5

This time, the Docker container ran successfully without any port conflict.

3.2. Expose Free Port

We can also resolve the above issue by exposing a free port while running the Docker container. We can find open ports in Linux using the ss or netstat command:

$ docker run -itd -e POSTGRES_USER=baeldung -e POSTGRES_PASSWORD=baeldung  -p 8082:5432 -v /data:/var/lib/postgresql/data --name postgresql-baeldung postgres
  154f66d3ba8bee4dafba092137311c43b950c31884e199d34d2b1d301496f9b5

It’s important to make sure we remove the stopped container “postgresql-baeldung” before running the fresh container.

4. Similar Port Binding Issue

In Docker, we can also face another issue similar to the “*Error bind: address already in use.*” In this issue, we get the following error:

"Bind for 0.0.0.0:8080 failed: port is already allocated."

The “port is already allocated” issue occurs if we run two different Docker containers on the same port. Let’s run the “postgresql-baeldung” container on 8080 port:

$ docker run -itd -e POSTGRES_USER=baeldung -e POSTGRES_PASSWORD=baeldung  -p 8080:5432 -v /data:/var/lib/postgresql/data --name postgresql-baeldung postgres
  5bddeacbe97229e4ee9cf2ed571fea309651f6cf6fecf433f22255e8cc506277
docker: Error response from daemon: driver failed programming external connectivity
  on endpoint postgresql-baeldung (b3469040c1fe37509c792e206e68d02ccc95a51b3353809b9462d15f6d670cc9):
  Bind for 0.0.0.0:8080 failed: port is already allocated.

The solution to the “Bind for 0.0.0.0:8080 failed: port is already allocated” issue is similar to the one discussed above. All we need to do is either free up the port, or use another available port.

One of the key differences between the issues is that the “address already in use” issue occurs when we run a Docker container on a port where a process is already running on the host, while the “port is already allocated” issue occurs when we try to run a Docker container with the same port on which a Docker container is already running.

5. Conclusion

In this article, we demonstrated how to resolve the “address already in use” issue in Docker. First, we analyzed the cause of the issue. Then we resolved it using different methods. Finally, we explored a similar issue related to the bind address.