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.

  1. 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.