node:lts-buster-slim
이미지로 띄운 Node 서버 컨테이너에서 다음과 같은 에러 로그 발생
2024-02-05 14:04:23 Error: listen EADDRINUSE: address already in use :::3000
2024-02-05 14:04:23 at Server.setupListenHandle [as _listen2] (node:net:1872:16)
2024-02-05 14:04:23 at listenInCluster (node:net:1920:12)
2024-02-05 14:04:23 at Server.listen (node:net:2008:7)
2024-02-05 14:04:23 at Function.listen (/usr/src/app/node_modules/express/lib/application.js:635:24)
2024-02-05 14:04:23 at Function.<anonymous> (/usr/src/app/src/server.js:13:7)
2024-02-05 14:04:23 at Function.emit (node:events:518:28)
2024-02-05 14:04:23 at Function.emit (node:domain:488:12)
2024-02-05 14:04:23 at /usr/src/app/db/index.js:17:13
2024-02-05 14:04:23 at processTicksAndRejections (node:internal/process/task_queues:95:5)
2024-02-05 14:04:23 Emitted 'error' event on Server instance at:
2024-02-05 14:04:23 at emitErrorNT (node:net:1899:8)
2024-02-05 14:04:23 at processTicksAndRejections (node:internal/process/task_queues:82:21) {
2024-02-05 14:04:23 code: 'EADDRINUSE',
2024-02-05 14:04:23 errno: -98,
2024-02-05 14:04:23 syscall: 'listen',
2024-02-05 14:04:23 address: '::',
2024-02-05 14:04:23 port: 3000
2024-02-05 14:04:23 }
2024-02-05 14:04:23
2024-02-05 14:04:23 Node.js v20.11.0
2024-02-05 14:04:23 [nodemon] app crashed - waiting for file changes before starting...
일반적으로 "이미 사용 중인 주소" 문제는 호스트 머신에서 이미 사용 중인 포트를 expose 하려는 경우 발생하는데, 특이하게도 호스트에서 해당 포트를 점유하고 있지 않은데도 문제가 발생하였다.
호스트 컴퓨터에서 검색해 보니 3000번 포트는 도커 서비스에서 사용하고 있다고 한다.
> lsof -i :3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
com.docke 12408 apple 1393u IPv6 0xfe7ad82bd8a75cf1 0t0 TCP *:hbci (LISTEN)
그리하여 해당 컨테이너에 exec
명령으로 접근하여 컨테이너 내부에서 포트 문제를 해결해보기로 하였다.
이 포트 문제를 해결하기 위해 우선 기존 프로세스를 찾아 종료하기 위해 PID를 확인하는 과정이 필요하다. lsof
명령어를 활용하면 특정 포트에서 실행 중인 프로세스의 ID를 알려준다.
컨테이너 안에 접근해서 확인해보면 lsof
패키지가 기본적으로 설치되어 있지 않아서, 설치를 먼저 진행하였다. 그런 다음 3000번 포트에서 실행 중인 노드 프로세스를 찾아 종료 시켜주었다.
> apt-get update
> apt-install lsof
> lsof -i:3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 395 root 27u IPv6 262410 0t0 TCP *:3000 (LISTEN)
> kill -9 395
서버 구성에 nodemon 설정이 포함되어 있어, 프로젝트 파일에 변경을 추가하여 저장하니 포트 문제가 해결되고 노드 서버는 자동으로 3000번 포트에서 다시 돌아가게 된다.
https://www.baeldung.com/linux/docker-address-already-in-use
관련 정보를 찾다 보니 대부분의 케이스가 호스트에서 사용 중인 포트를 컨테이너 포트로 노출하려 할 때 발생한 경우였고, 내가 겪은 케이스는 그와는 다른 문제 같아 보였다.
nodemon issue에 올라온 내용을 보면 동일 증상을 겪고 있는 사용자들의 의견이 꾸준히 리포트 되고 있는 것 같다. 그러다 스택오버플로우에서 찾은 임시 방편(?)중 하나가 있다. 필요한 경우라면 아래 내용을 채택할 수도 있겠다.
package.json에 충돌이 나는 포트의 프로세스를 kill 한 뒤 node 서버를 실행시키는
npm run inspect
명령을 추가하고, nodemon에서 이 명령을 호출한다.