Node.js 개발을 하다 보면 누구나 한 번쯤은 마주치게 되는 그 악명 높은 에러 메시지가 있습니다. 바로 Error: listen EADDRINUSE: address already in use
에러입니다.
처음 이 에러를 만났을 때는 “뭔가 잘못됐나?”하며 당황스러우셨을 텐데요. 사실 이 에러는 생각보다 흔하게 발생하는 문제이고, 해결법도 명확합니다. 오늘은 이 에러가 왜 발생하는지, 그리고 어떻게 해결할 수 있는지 차근차근 알아보겠습니다.
EADDRINUSE 에러란 무엇인가?
EADDRINUSE
는 “Error: Address Already in Use”의 줄임말입니다. 이 에러는 Node.js 애플리케이션이 이미 다른 프로세스에서 사용 중인 포트에 바인딩하려고 할 때 발생합니다.
주요 발생 상황
- 이전에 실행했던 Node.js 서버가 완전히 종료되지 않은 경우
- 같은 포트를 사용하는 다른 애플리케이션이 실행 중인 경우
- Ctrl+Z로 프로세스를 백그라운드로 보낸 경우 (Ctrl+C 대신)
- 개발 환경에서 여러 서버를 동시에 실행하려는 경우
실제 에러 메시지는 다음과 같이 나타납니다:
Error: listen EADDRINUSE: address already in use :::3000
at Server.setupListenHandle [as _listen2] (node:net:1330:16)
at listenInCluster (node:net:1378:12)
at Server.listen (node:net:1465:7)
원인파악하기: 포트 사용 중인 프로세스 확인하기
문제를 해결하기 위해서는 먼저 어떤 프로세스가 해당 포트를 사용하고 있는지 확인해야 합니다. 운영체제별로 확인 방법이 다르니 각각 살펴보겠습니다.
운영체제별 포트 확인 명령어
운영체제 | 명령어 | 설명 |
---|---|---|
Linux/macOS | lsof -i :3000 |
3000번 포트를 사용하는 프로세스 확인 |
Linux/macOS | netstat -anp | grep :3000 |
netstat으로 포트 확인 |
Windows | netstat -ano | findstr :3000 |
Windows에서 포트 확인 |
Windows | tasklist /fi "PID eq [PID번호]" |
특정 PID의 프로세스 정보 확인 |
Linux/macOS에서 확인하기
가장 일반적으로 사용되는 방법은 lsof
명령어입니다:
# 3000번 포트를 사용하는 프로세스 확인
sudo lsof -i :3000
# 결과 예시
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 12345 user 23u IPv6 0x12345 0t0 TCP *:3000 (LISTEN)
netstat
명령어로도 확인할 수 있습니다:
# LISTEN 상태의 3000번 포트 확인
netstat -anp | grep :3000 | grep LISTEN
Windows에서 확인하기
Windows에서는 netstat
과 tasklist
를 조합해서 사용합니다:
# 1단계: 포트 사용 프로세스의 PID 확인
netstat -ano | findstr :3000
# 2단계: PID로 프로세스 정보 확인 (예: PID가 12345인 경우)
tasklist /fi "PID eq 12345"
해결방법1: 해당 프로세스 종료하기
포트를 사용하는 프로세스를 확인했다면, 이제 해당 프로세스를 종료해야 합니다.
Linux/macOS에서 프로세스 종료
PID를 확인한 후 kill
명령어로 프로세스를 종료합니다:
# 부드럽게 종료 시도
kill 12345
# 강제 종료 (위 명령어가 작동하지 않을 때)
kill -9 12345
# 또는 모든 node 프로세스 종료
killall node
Windows에서 프로세스 종료
Windows에서는 여러 방법으로 프로세스를 종료할 수 있습니다:
# 명령 프롬프트에서 PID로 종료
taskkill /PID 12345 /F
# 모든 Node.js 프로세스 종료
taskkill /F /IM node.exe
작업 관리자를 이용한 방법도 있습니다. Ctrl+Shift+Esc로 작업 관리자를 열고, “세부 정보” 탭에서 node.exe 프로세스를 찾아 “작업 끝내기”를 클릭합니다.
해결방법2: 간편한 해결법 (kill-port 패키지 사용)
매번 복잡한 명령어를 입력하는 것이 번거롭다면, kill-port
npm 패키지를 사용하는 것이 훨씬 편리합니다.
kill-port 패키지 사용법
# npx로 일회성 사용 (설치 없이)
npx kill-port 3000
# 여러 포트를 동시에 종료
npx kill-port 3000 3001 8080
# 전역 설치 후 사용
npm install -g kill-port
kill-port 3000
이 패키지는 Windows, macOS, Linux 모든 환경에서 동일하게 작동하므로 크로스 플랫폼 개발 환경에서 특히 유용합니다.
해결방법3: 포트 변경하기
때로는 프로세스를 종료하는 것보다 다른 포트를 사용하는 것이 더 나은 해결책일 수 있습니다.
Express.js에서 포트 변경
const express = require('express');
const app = express();
// 포트를 환경변수로 설정하거나 기본값 사용
const PORT = process.env.PORT || 3001; // 3000 대신 3001 사용
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
동적 포트 할당
Node.js에서 사용 가능한 포트를 자동으로 찾도록 설정할 수도 있습니다:
const express = require('express');
const app = express();
// 포트를 0으로 설정하면 사용 가능한 포트를 자동으로 할당
const server = app.listen(0, () => {
const port = server.address().port;
console.log(`Server running on port ${port}`);
});
환경변수로 포트 관리
개발, 테스트, 프로덕션 환경에서 각각 다른 포트를 사용하도록 설정할 수 있습니다:
# Linux/macOS
export PORT=5000
node app.js
# Windows CMD
set PORT=5000
node app.js
# Windows PowerShell
$env:PORT=5000
node app.js
EADDRINUSE 에러는 처음에는 당황스럽지만, 원인과 해결법을 알고 나면 충분히 대처할 수 있는 문제입니다.
핵심은 어떤 프로세스가 포트를 사용하고 있는지 확인하고, 그 프로세스를 적절히 종료하거나 다른 포트를 사용하는 것입니다. kill-port
패키지나 적절한 에러 처리를 구현해두면 개발 과정에서 훨씬 수월하게 이 문제를 해결할 수 있습니다.
무엇보다 중요한 것은 개발 중에 서버를 종료할 때 올바른 방법(Ctrl+C)을 사용하고, 프로덕션 환경에서는 적절한 프로세스 관리 도구를 활용하는 것입니다. 이런 습관을 들이면 EADDRINUSE 에러를 크게 줄일 수 있을 것입니다.