0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Linuxでポート競合を解決する!よくある場面別コマンド

0
Posted at

はじめに

開発やサーバー運用をしていると、突然アプリケーションが起動しなくなり「ポートが既に使用されています」というエラーに遭遇したことはありませんか?

このような ポート競合(ポート衝突) は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 -tulpnss -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:ローカル開発で「ポート使用中」エラーが出た

やることの順序:

  1. ポート確認

    netstat -tulpn | grep :3000
    
  2. 詳細確認(念のため)

    lsof -i :3000
    
  3. プロセス終了

    kill $(lsof -t -i :3000)
    
  4. アプリケーション再起動

    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-forwarddocker 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 PIDsudo fuser -k ポート/tcp
  • Kubernetes環境ではpkill -f port-forward も活用
  • systemd管理サービスはsystemctlで操作 が安全

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?