Skip to content
DevOps2026-09-073 分钟阅读

端口被占用怎么办?EADDRINUSE / Port already in use 全平台解决指南

现象:项目起不来,一行报错

Error: listen EADDRINUSE: address already in use :::3000

或英文形态:

Port 3000 is already in use

含义一句话:你要监听的端口已经被另一个进程占着。开发服务器、数据库、Docker 容器、上一个没退干净的 node 进程——都可能是占用者。

第一步:查出谁在占端口

macOS / Linux

lsof -ti:3000          # 只打印占用 3000 端口的进程 PID(脚本友好)
lsof -i:3000           # 人读版:PID、进程名、用户一目了然

Windows(PowerShell)

netstat -ano | findstr :3000     # 最后一列是 PID
tasklist /fi "PID eq 12345"      # 用 PID 查进程名

第二步:处理占用进程

情况 A:旧的开发服务器(最常见)

上次 Ctrl+C 没杀干净,或者终端关了进程还活着。直接结束它:

# macOS / Linux
kill -9 $(lsof -ti:3000)

# Windows(PowerShell)
taskkill /PID 12345 /F

判断依据lsof -i:3000 显示的进程名是你自己的(node、vite、next-server 等)→ 放心杀。

情况 B:是别的服务在用这个端口

进程名不是你的项目(比如 postgres、mongod、另一个团队的服务)——别杀它,换自己的端口

# 按框架改启动端口
next dev -p 3001          # Next.js
vite --port 3001          # Vite
npm start -- --port 3001  # 多数 CLI 支持

情况 C:Docker 容器映射了该端口

lsof 里进程名是 docker-proxy

docker ps --filter "publish=3000"    # 找到容器
docker stop <容器名>                  # 停掉,或改 compose 里的端口映射

为什么要 kill -9?kill 不行吗?

先试普通 kill(发 SIGTERM,进程可以优雅退出),几秒后还在再 kill -9(SIGKILL,强杀)。开发场景的残留进程通常无所谓优雅,直接 -9 省事;生产数据库等有状态服务永远先用普通 kill。

预防:让端口冲突不再发生

  1. 固定开发端口约定:团队约定 3000/3001/3002 分工,别抢;
  2. 用 ports 变量.env 里放 PORT=3001,配置引用变量而不是硬编码;
  3. 退出走 Ctrl+C 而不是关终端:大多数 dev server 会随终端会话清理,但后台启动(&/nohup)的不会——后台起的进程要记 PID
  4. 端口 0 = 随机分配:写测试/脚本时监听 port 0 让系统分配空闲端口,从根上避开冲突。

高频追问

3000 端口在 Mac 上查出来是 ControlCenter?

macOS Monterey 起系统服务会占用若干端口(AirPlay 接收器常占 5000/7000)。ControlCenter 占 3000 属系统行为,别杀,改用自己的端口最省事。

杀完进程端口还是占用?

两种可能:①进程处于 TIME_WAIT 状态(一分钟内自动释放,等一下再试);②有父进程拉起了新的子进程(Docker restart 策略、pm2、systemd)——找到管理者停它,而不是反复杀子进程。

EADDRINUSE 里 :::3000 的三个冒号是什么?

::: 是 IPv6 全地址 :: 加端口分隔符——你的服务试图监听 IPv6 的 3000 端口。与 IPv4 的 0.0.0.0:3000 是两个不同的监听,但多数程序(和这个报错场景)双栈共享,按占用处理即可。

一键脚本(放 alias 里)

# macOS/Linux:释放指定端口
freeport() { lsof -ti:"$1" | xargs kill -9 2>/dev/null && echo "port $1 freed" || echo "port $1 was free"; }
# 用法:freeport 3000

Windows 版(PowerShell profile):

function freeport($p) { Get-NetTCPConnection -LocalPort $p -ErrorAction SilentlyContinue |
  ForEach-Object { Stop-Process -Id $_.OwningProcess -Force } }

排查清单

  1. lsof -ti:3000(Windows:netstat -ano | findstr :3000)拿到 PID
  2. 看进程名:自己的残留 → 杀;别人的服务 → 换端口;docker-proxy → 停容器
  3. 杀完还占:等 TIME_WAIT 或找进程管理者
  4. 长期方案:端口约定进 .env、后台进程记 PID、脚本用 port 0

本文由 ToolVault 工具匣 提供。开发部署相关工具:Dockerfile 生成器Linux 命令速查HTTP 状态码速查。访问 首页 查看更多开发者工具。


广告