「port already in use」の原因と対処法|基本的な解決手順
開発サーバーや Docker コンテナを起動したときに port already in use と出るなら、まず疑うべきは 同じポートを別のプロセスが先に使っている 状態です。原因の切り分けは難しくありません。どのポートで失敗したかを確認し、そのポートをつかんでいるプロセスを特定して、止めるか、別のポートへ変更すれば解決できます。
このエラーは Node.js の EADDRINUSE、Docker の port is already allocated、各種フレームワークの起動失敗として表れます。見た目は違っても、やることはほぼ同じです。
- 先に結論: 「どのポートが競合しているか」を確認し、「誰が使っているか」を見つける のが最短です
- よくある原因: 前回の開発サーバーが残っている、別アプリが待ち受け中、Docker がホスト側で同じポートを公開している
- 基本対応: 競合プロセスを止めるか、アプリ側のポート番号を変える
- 注意点: すぐ
killせず、その PID が本当に止めてよいプロセスか確認する
このエラーが出る主な原因
まずは、何が起きているエラーなのかを整理します。
1. すでに別プロセスが待ち受けている
いちばん多いのはこれです。たとえば 3000 番で React や Node.js の開発サーバーを起動しようとしたのに、前回起動したプロセスや別のツールがすでに 3000 を LISTEN 状態で使っているケースです。
Node.js の公式ドキュメントでも、EADDRINUSE は「ローカルアドレスへの bind に失敗し、別サーバーがそのアドレスを占有している状態」と説明されています。つまり、アプリのコードより前に OS 側で競合が起きています。
2. 前回のプロセスが正常終了していない
ホットリロード中の強制終了、ターミナルを閉じた直後、IDE の停止失敗などで、見えないままプロセスだけ残ることがあります。
この状態では、見た目は止まっていても、ポートだけは使われ続けます。再起動したのに同じエラーが出るときは、このパターンを疑うと早いです。
3. Docker がホスト側ポートをすでに使っている
Docker では -p 8080:80 のように、ホスト側の 8080 をコンテナへ公開します。ここでホストの 8080 が別アプリに使われていると、Docker 側は Bind for 0.0.0.0:8080 failed や port is already allocated で起動できません。
Docker Docs でも、原因として次の 2 つが挙げられています。
- そのポートを別アプリが使っている
- 以前のコンテナが正しく停止できず、ポートを握ったままになっている
まず試す基本的な解決手順
ここからは、実際に解決するための流れを順番に見ます。確認時点は 2026年4月、Windows 10/11 と一般的な Linux 系 CLI、Docker の基本挙動を前提にしています。
ここがポイント: エラー文のポート番号を見て、そのポートを使っている PID を調べる。この 2 段階で大半は片付きます。
手順1. エラーに出たポート番号を確認する
たとえば次のような表示です。
Error: listen EADDRINUSE: address already in use :::3000
Bind for 0.0.0.0:8080 failed: port is already allocated
この場合、調べる対象はそれぞれ 3000 と 8080 です。ここを読み飛ばすと、関係ないプロセスを止めて遠回りになります。
手順2. そのポートを使っているプロセスを特定する
Windows の例
netstat は待受中のポートと PID を確認できます。Microsoft Learn でも、-a は待受ポートを含めて表示し、-o は PID を表示するオプションとして案内されています。
netstat -aon | findstr :3000
出力例:
TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 12345
この例では 12345 が PID です。
PowerShell を使うなら、Get-NetTCPConnection でローカルポートと所有プロセスを確認する方法も分かりやすいです。
Get-NetTCPConnection -LocalPort 3000 | Select-Object LocalAddress,LocalPort,State,OwningProcess
Linux の例
Linux では ss が定番です。ss はソケット情報を確認するためのツールで、待受状態だけを見るなら次の形が使いやすいです。
ss -ltnp | grep :3000
出力例:
LISTEN 0 511 0.0.0.0:3000 0.0.0.0:* users:(("node",pid=12345,fd=23))
fuser でも、特定ポートを使っている PID を見つけられます。
fuser 3000/tcp
手順3. 止めてよいプロセスなら終了する
ここが実作業です。ただし、いきなり強制終了しない のが基本です。DB、リバースプロキシ、社内ツールなど、本番に近い常駐プロセスを止めると別の障害になります。
Windows の例
PID を指定して停止します。
taskkill /PID 12345 /F
PowerShell ならこちらでも構いません。
Stop-Process -Id 12345 -Force
Linux の例
まずは通常終了を試します。
kill 12345
それでも残るときだけ強制終了を検討します。
kill -9 12345
fuser にはポートを使っているプロセスを終了する -k オプションがありますが、便利なぶん誤爆しやすいので、PID を見てから使うほうが安全です。
手順4. 止められないなら、アプリ側のポートを変える
競合相手を止められないなら、自分のアプリ側を動かしたほうが早い場面もあります。ローカル開発では特に現実的です。
Node.js 系の例
PORT=3001 npm run dev
PowerShell なら次のように指定します。
$env:PORT=3001
npm run dev
Docker の例
コンテナ内部のポートはそのままで、ホスト側だけ変えられます。
docker run -p 8081:80 nginx
これは「コンテナの 80 番」は変えずに、「ホストの 8081 番」で受ける設定です。Docker で詰まりやすいのは、変えるべきなのが左側のホストポート だという点です。
入力例と出力例で流れを確認
手順を一度、短く通してみます。
例1. Node.js の開発サーバーが 3000 番で起動できない
入力:
Error: listen EADDRINUSE: address already in use :::3000
確認:
netstat -aon | findstr :3000
出力:
TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 12345
対応:
taskkill /PID 12345 /F
再実行:
npm run dev
例2. Docker で 8080 番の公開に失敗する
入力:
Bind for 0.0.0.0:8080 failed: port is already allocated
考えるべき点は 2 つです。
- ホストの
8080を別アプリが使っていないか - 以前のコンテナが
8080を公開したまま残っていないか
対応例:
docker ps
docker port <container-name>
必要ならホスト側をずらします。
docker run -p 8081:80 nginx
よくある失敗と見分け方
ここは初心者がつまずきやすいところです。
PID が分かったらすぐ消してしまう
PID を見つけた時点では、まだ「犯人が分かった」だけです。止めてよいかは別問題です。
- 開発サーバーなら止めてよいことが多い
- PostgreSQL、MySQL、Nginx、Apache などは影響範囲を確認してから止める
- Docker Desktop 関連プロセスをむやみに止めると別の起動不良を招くことがある
Docker の内側と外側のポートを混同する
8080:80 は ホスト:コンテナ です。競合するのは左側です。
8080:80で失敗したら、見直すのはホストの8080- コンテナ内アプリが
80で待ち受けていても、それ自体は原因ではないことが多い
port already in use と permission denied を混同する
似た場面で出ますが、別の問題です。
port already in use: そのポートは別プロセスが使用中EACCESやpermission denied: 権限不足で bind できない
エラー文が違えば、対処も変わります。ここを混ぜると調査が長引きます。
実務での使いどころと再発防止
単発で直すだけなら、PID を調べて止めれば終わりです。ただ、開発や検証を繰り返す現場では、毎回同じ詰まり方をしない仕組みも効きます。
ルール化しやすい対策
- 開発サーバーの既定ポートをチームでずらす
.envでPORTを切り替えられるようにする- Docker Compose ではホストポートの重複を避ける
- 停止処理を
Ctrl+C任せにせず、終了手順をそろえる - 競合時に
3000から3001へ自動フォールバックする仕組みを入れる
チーム開発で特に効く確認ポイント
- README やセットアップ手順に「使うポート一覧」を書く
- ローカルで DB、API、フロントエンドが何番を使うか固定する
- リバースプロキシやコンテナを使う場合は、ホストポートと内部ポートを分けて管理する
関連ツールと代替手段
同じ「ポート競合の解消」でも、状況によって使いやすい方法は変わります。
手順中心で確認したいなら
- Windows:
netstat、Get-NetTCPConnection、taskkill - Linux:
ss、fuser、kill
コンテナ中心なら
docker psで稼働中コンテナを確認docker portで公開ポートを確認-p HOST:CONTAINERの左側を変更して回避
アプリ側で吸収したいなら
.envでポートを切り替える- 開発ツールの設定で既定ポートを変更する
- 競合時の自動再割り当て機能があるツールは活用する
迷ったときの最短チェックリスト
最後に、実際の作業ではこの順で見れば十分です。
- エラー文のポート番号を確認する
- そのポートを使っている PID を調べる
- 止めてよいプロセスか確認する
- 止められるなら終了する
- 止められないならアプリ側のポートを変える
- Docker ならホスト側ポートを見直す
port already in use は、難しいネットワーク障害というより、「同じ席を先に誰かが使っている」状態の確認作業です。次に詰まったら、エラー文のポート番号、PID、ホスト側ポートの 3 点だけを先に見てください。そこで原因が見えれば、復旧はかなり早くなります。
