はじめに
開発やサーバー運用をしていると、突然アプリケーションが起動しなくなり「ポートが既に使用されています」というエラーに遭遇したことはありませんか?
このような ポート競合(ポート衝突) はLinux環境では頻繁に起こります。特に以下のような場面で多く見られます。
- ローカル開発環境で複数のサービス(DB、API、フロントエンド)を同時に起動
- Kubernetes環境で
kubectl port-forwardが残ったまま新しいものを起動 - 予期しないバックグラウンドプロセスがポートを占有
本記事では、実務で頻出する5つの場面ごと に、最適なコマンドと解決方法を紹介します。初心者でもすぐに対応できるように、コマンドの選び分けと実行フローをまとめました。
よくあるポート競合の場面
ポート競合が起こる代表的な場面を整理しておきます。
| 場面 | 原因 | 解決の難易度 |
|---|---|---|
| ローカル開発で同じポートの複数起動 | うっかり2回起動した | 簡単 |
| 前回のプロセスが残ったまま | kill失敗 or 自動起動設定 | 簡単 |
| kubectl port-forward の残存 | ターミナル閉じ忘れ | 簡単 |
| システムサービスとの競合 | Nginx と別のHTTPサーバー | 注意が必要 |
| バックグラウンドデーモン | systemd管理下のプロセス | 事前確認が重要 |
このうち、ほとんどの場面は 3つのコマンド で対応できます。
ステップ1:ポートを使用中のプロセスを特定する
🎯 最速確認コマンド:netstat
最も手軽で一般的な方法です。まずはこれで確認しましょう。
netstat -tulpn | grep :9090
出力例:
tcp6 0 0 :::9090 :::* LISTEN 12345/prometheus
コマンド説明:
-
-t:TCPポートのみ表示 -
-u:UDPポートのみ表示(必要に応じて) -
-l:LISTENしているポートのみ -
-p:プロセス名とPIDを表示 ← これが重要! -
-n:サービス名ではなくポート番号で表示 -
grep :9090:ポート9090に絞り込み
netstat -tulpnとss -tulpnの違い
netstatはサポート終了予定ですが、まだ広く使われています。新しい環境ではss推奨です。出力形式は似ていますが、ssの方が高速です。
詳細情報が欲しい場合:lsof
ポートを使用しているプロセスの詳細情報が欲しいときは lsof を使います。
lsof -i :9090
出力例:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
prometheus 12345 root 8u IPv6 12345 0t0 TCP *:9090 (LISTEN)
lsof は以下の情報を表示するため、より詳細な調査に向いています。
- COMMAND:プロセス名
- PID:プロセスID
- USER:実行ユーザー
- FD:ファイルディスクリプタ
- TYPE:接続タイプ(IPv4/IPv6)
root権限が必要な場合がある
lsof -iを実行する際、他ユーザーのプロセスが見えない場合は、前にsudoを付けてください。
新しい環境推奨:ssコマンド
より高速で効率的な ss コマンドも紹介しておきます。
ss -tulpn | grep :9090
出力形式は netstat とほぼ同じですが、処理が高速です。新しいLinux環境(Ubuntu 20.04+など)では ss の使用が推奨されています。
ステップ2:ポート使用プロセスを終了する
🎯 最速終了方法:fuserコマンド
ポートを使用しているプロセスを素早く終了させるには fuser が便利です。
# プロセス確認(kill前に必ず確認!)
fuser -v 9090/tcp
# プロセス終了(graceful)
kill $(lsof -t -i :9090)
# または強制終了
sudo fuser -k 9090/tcp
実際の例:
# ステップ1:どんなプロセスが使用中か確認
$ netstat -tulpn | grep :8080
tcp6 0 0 :::8080 :::* LISTEN 5432/python
# ステップ2:PIDを確認したうえで終了
$ kill 5432
# ステップ3:ポートが解放されたか確認
$ netstat -tulpn | grep :8080
# → 何も表示されなくなればOK
強制終了(kill -9)には注意
fuser -k 9090/tcpやその他の強制終了は、プロセスがデータを保存していないことを確認してから実行してください。予期しないデータロスやファイル破損が起こります。
Kubernetes環境での対応
kubectl port-forwardが占有しているポートの場合は特に注意が必要です。
# port-forward プロセスを確認
ps aux | grep port-forward
# port-forward関連プロセスをすべて終了
pkill -f "port-forward"
# 特定ポートの port-forward だけ終了する場合
pkill -f "port-forward.*9090"
ステップ3:ポート解放確認と再起動
プロセスを終了した後は、必ずポートが解放されたか確認してから、アプリケーションを再起動します。
# ポートが解放されたか確認
netstat -tulpn | grep :9090
# → 何も出力されなくなればOK
# 新しいアプリケーションを起動
python app.py --port 9090
場面別コマンド選択ガイド
ここまでのコマンドを整理して、実際の場面ごとにどのコマンドを使うべきかをまとめました。
場面1:ローカル開発で「ポート使用中」エラーが出た
やることの順序:
-
ポート確認
netstat -tulpn | grep :3000 -
詳細確認(念のため)
lsof -i :3000 -
プロセス終了
kill $(lsof -t -i :3000) -
アプリケーション再起動
npm start --port 3000
場面2:複数のサービスが起動しているか一覧確認したい
開発環境で複数のマイクロサービスが起動しているとき、どのサービスがどのポートを使っているか確認したい場合:
# よく使われるポートを一括確認
for port in 3000 5000 8000 8080 9000 9090; do
echo "=== ポート $port ==="
netstat -tulpn | grep ":$port " || echo "使用されていません"
done
出力例:
=== ポート 3000 ===
tcp6 0 0 :::3000 :::* LISTEN 2345/node
=== ポート 5000 ===
使用されていません
=== ポート 8000 ===
tcp6 0 0 :::8000 :::* LISTEN 3456/python
場面3:Kubernetes/Docker環境でのポート競合
kubectl port-forwardやdocker run -pでポート競合が起こった場合:
# port-forward が残っていないか確認
ps aux | grep port-forward
# 該当するport-forwardを終了
pkill -f "port-forward.*9090"
# Dockerコンテナを確認
docker ps | grep -i 9090
場面4:システムサービス(Nginx など)との競合
HTTPサーバーが複数起動しているか確認する場合:
# HTTP/HTTPS関連ポートを確認
netstat -tulpn | grep -E ':(80|443) '
# プロセス詳細確認
lsof -i :80
既に Nginx が起動していて、別の Apache を起動しようとしている場合など、このコマンドで競合を検出できます。
systemdで管理されているサービスの場合
sudo systemctlで管理されているサービス(nginx、httpd など)を終了する場合は、直接killではなくsystemctl stopを使いましょう。
# ❌ 非推奨
sudo kill 1234
# ✅ 推奨
sudo systemctl stop nginx
場面5:バックグラウンドで動いているデーモンを見つけたい
# バックグラウンドで起動しているすべてのポート使用状況
netstat -tlpn | grep LISTEN
# ユーザー別で確認
lsof -i -u $(whoami)
よくあるエラーと対処法
エラー:Address already in use
Error: listen EADDRINUSE: address already in use :::8080
対処:
netstat -tulpn | grep :8080
kill $(lsof -t -i :8080)
エラー:lsof: command not found
lsofがインストールされていない場合は、以下でインストールしてください。
# Ubuntu/Debian
sudo apt-get install lsof
# CentOS/RHEL
sudo yum install lsof
# macOS
brew install lsof
エラー:Permission denied
他ユーザーのプロセスが使用しているポートの場合は、sudoが必要です。
sudo netstat -tulpn | grep :9090
sudo lsof -i :9090
sudo kill -9 $(sudo lsof -t -i :9090)
実用コマンド集(コピペ対応)
よく使うワンライナーをまとめました。状況に応じてコピペできます。
# ポート9090を確認
netstat -tulpn | grep :9090
# ポート9090を強制終了
sudo fuser -k 9090/tcp
# ポート範囲を確認(9000-9100番台)
netstat -tulpn | grep -E ':(90[0-9][0-9]|910[0-0]) '
# ポート9090を使用しているPIDだけ取得
lsof -t -i :9090
# ポート9090を使用するプロセスを確認して詳細表示
PID=$(lsof -t -i :9090)
ps -p $PID -o pid,user,command --no-headers
# 複数のport-forwardを終了
pkill -f port-forward
# 利用可能なポートを探す関数
check_port() {
local port=$1
if netstat -tulpn 2>/dev/null | grep -q ":$port "; then
echo "ポート$port は使用中です"
netstat -tulpn | grep ":$port "
return 1
else
echo "ポート$port は利用可能です"
return 0
fi
}
# 使用例:check_port 9090
参考:各コマンドの使い分け表
| 状況 | 推奨コマンド | 理由 |
|---|---|---|
| とりあえず確認したい | netstat -tulpn | grep :ポート |
最も一般的、出力が見やすい |
| 詳細情報が欲しい | lsof -i :ポート |
プロセス情報が豊富 |
| 高速に確認したい(新環境) | ss -tulpn | grep :ポート |
netstatより高速 |
| すぐに終了させたい | sudo fuser -k ポート/tcp |
ワンステップで終了 |
| ユーザー別に確認 | lsof -i -u ユーザー名 |
セキュリティ監査向け |
まとめ
ポート競合問題は、Linux/Unix運用で避けて通れないトラブルですが、適切なコマンドを知っていれば数秒で解決できます。本記事のポイントをおさらいします。
-
まずは
netstat -tulpn | grep :ポートで確認が基本 -
詳細が欲しければ
lsof -i :ポートで追加情報を取得 - 終了させるなら
kill PIDかsudo fuser -k ポート/tcp -
Kubernetes環境では
pkill -f port-forwardも活用 -
systemd管理サービスは
systemctlで操作 が安全