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 the beginners face while working with Docker. We’ll also look into the root cause of this issue and different approaches to resolve it.
2. Understanding the Problem
In Docker, the issue “address already in use” occurs when we try to expose a container port that is already acquired on the host machine.
To resolve the issue, first, we need to reproduce the problem. 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.
Let’s now 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 cannot 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 have successfully removed the “postgresql-baeldung” Docker container.
3. Solving the Bind Address Issue
Till now, we’ve reproduced the issue and understood the root cause of the problem. So let’s now look into 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 is not installed in Linux.
Let’s check out the command to install the lsof:
$ yum install -y lsof
Using the above command, we’ve successfully installed the lsof package. Let’s look into the command to get the PID of the process using the lsof command:
$ lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 78812 root 66u IPv6 0xe28ed26f1f48e597 0t0 TCP *:http-alt (LISTEN)
Here, 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
$ 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
Here, we have to make sure that we should 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 some other available port.
One of the key differences between both the issues is that the issue “address already in use” occurs when we run a Docker container on a port on which 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.
This tutorial demonstrated how to resolve the “address already in use” issue in Docker. First, we understood the cause of the issue. Later we resolved it using different ways. At last, we also explored a similar issue related to the bind address.