EADDRINUSE Neden Olur ve kill -9 Neden Yetmez?

Node.js, Python veya Vite geliştirme sunucusunu başlattığınızda `Error: listen EADDRINUSE: address already in use :::3000` hatası alıyorsanız, işletim sistemi çekirdeği o TCP portuna başka bir soketin veya `TIME_WAIT` durumundaki bir bağlantının bağlı olduğunu söylüyordur.

Tek bir PID'yi körlemesine öldürmek çoğu zaman sorunu çözmez; çünkü nodemon, PM2, systemd veya Docker daemon gibi bir üst proses (parent process) alt işçiyi saniyeler içinde yeniden başlatır ya da portu `docker-proxy` arkasına gizler.

Bash
Error: listen EADDRINUSE: address already in use :::3000
    at Server.setupListenHandle [as _listen2] (node:net:1904:16)
    at listenInCluster (node:net:1961:12)

Windows, Linux ve macOS'ta Portu Tutan Prosesi Bulma

Üç işletim sisteminde de ek araç kurmadan portu tutan PID'yi görebilirsiniz. Ancak sadece PID numarasını görmek yerine, o prosesi kimin başlattığını (`ParentProcessId` / `PPID`) kontrol etmek zombi yeniden başlatmalarını önler.

Bash
# Linux / macOS (port 3000)
lsof -i :3000 -n -P
ss -tulpn | grep :3000

# Windows PowerShell (port 3000 + proses adı + üst proses)
Get-NetTCPConnection -LocalPort 3000 | Select-Object LocalPort, State, OwningProcess
Get-CimInstance Win32_Process -Filter "ProcessId = <PID>" | Select-Object ProcessId, ParentProcessId, CommandLine

Docker ve CI Ortamlarında Maskelenmiş Portlar

Konteyner içinde çalışan bir veritabanı veya web servisi portu tuttuğunda `lsof` host üzerinde yalnızca `docker-proxy` veya `com.docker.backend` gösterir. Gerçek sorumluyu bulmak için yayınlanan port eşlemesini konteyner listesiyle karşılaştırmak gerekir.

Bash
# Hangi Docker konteyneri 3000 veya 5432 portunu yayınlıyor?
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" | grep -E "3000|5432"

# Yalnızca çakışan konteyneri durdur
docker stop <CONTAINER_ID>

PortTree ile Proses Ağacını Tek Komutta Görün ve Temizleyin

Her seferinde işletim sistemine göre farklı `netstat` / `lsof` / PowerShell bayrakları hatırlamak yerine, sıfır bağımlılıklı açık kaynak aracım PortTree ile soketten kök prosese kadar tüm ağacı tek komutla listeleyebilir, önce nazikçe `SIGTERM` gönderip kapanmazsa sonlandırabilirsiniz.

Bash
# Kurulum veya klonlama sonrası port 3000 denetimi
python -m porttree --port 3000

# CI ön kontrolü: port boşsa exit 0, meşgulse exit 1
python -m porttree --assert-free 3000 --json

# Güvenli iki aşamalı temizlik (SIGTERM -> timeout -> SIGKILL)
python -m porttree --kill 3000

Kaynak: PortTree — Sıfır Bağımlılıklı Soket ve Proses Ağacı Denetçisi

Kaynak: Port çakışmaları ve proses ağaçları: PortTree mimarisi