Troubleshooting Port in Use Errors On Linux With Containers
Troubleshooting Port in Use Errors On Linux With Containers
When you encounter a “port in use” error on Linux, it typically means that another process is already using the port you are trying to bind to. Here’s how to troubleshoot and resolve this issue. NOTE: You may need superuser privileges to run some of these commands. If you run the commands without sudo
, you may not see all processes.
- Identify the Process Using the Port
You can use the
lsof
command to identify the process using the port. For example, to check if port 3000 is in use, you can run:lsof -i :3000
This will show you the process ID (PID) of the application using that port. Here’s a real world example:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python3 151820 root 57u IPv6 612694 0t0 TCP ip6-localhost:55996->ip6-localhost:3000 (ESTABLISHED)
node 152014 root 27u IPv6 615470 0t0 TCP *:3000 (LISTEN)
node 152014 root 31u IPv6 609261 0t0 TCP ip6-localhost:3000->ip6-localhost:55996 (ESTABLISHED)
In this example, the node
process with PID 152014 is listening on port 3000, but there is also a python3
process that has an established connection to it. We are interested in the node
process, since it is the one that is actively listening on port 3000.
Knowing that the node
process is using port 3000, while useful, doesn’t really tell us which application it is. To find out more about this process, we will run a few more commands.
First let’s check the command that started this process. You can do this with:
ps -p 152014 -o args=
or
cat /proc/152014/cmdline | xargs -0 echo
In this case, the output I got was:
node server/bin/www
Ok, so this is a Node.js application running a server. Useful, but not actionable yet. Let’s see if the environment variables give us more information. You will definitely need superuser privileges to run this command, otherwise you will not see the environment variables of processes owned by other users:
sudo cat /proc/152014/environ | xargs -0 -n1 echo
This is the output I got:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=[removed]
TAG_NAME=
NODE_ENV=production
HOME=/root
Not much useful information here either. Maybe this is a docker container? Let’s check the cgroup information:
cat /proc/152014/cgroup
The output I got was:
0::/system.slice/docker-7ea7265d4982c4cc56951ed2b0a0eb3eed70ba76c11b0f11dd1b79245680a1be.scope
Ah yes, this is a Docker container. The process is running inside a Docker container with the ID 7ea7265d4982c4cc56951ed2b0a0eb3eed70ba76c11b0f11dd1b79245680a1be
. Let’s check the Docker container to see which image it is using:
docker inspect 7ea7265d4982c4cc56951ed2b0a0eb3eed70ba76c11b0f11dd1b79245680a1be --format '{{.Config.Image}}'
Now we have the image name:
zwavejs/zwave-js-ui:latest
So, the process using port 3000 is a Node.js application running inside a Docker container based on the zwavejs/zwave-js-ui:latest
image.
Now that we know which application is using the port, we can decide what to do next. You can start your new container on a different port, or modify the existing container to use a new port or stop it if it is not needed.