Error: listen EADDRINUSE: address already in use の解決方法

Error: listen EADDRINUSE: address already in use の解決方法

このエラーは、Node.jsサーバーが指定されたポートを使用しようとした際に、すでに別のプロセスがそのポートを使用している場合に発生します。この問題の原因と解決方法について、詳細に説明します。

エラーの発生条件

  • サーバーが既に同じポートで起動している。
  • ポートを解放せずに再度使用しようとしている。
  • 他のプロセスがポートを占有している。
  • OSのポート管理設定に問題がある。

原因1: サーバーが重複して起動している

同じアプリケーションを複数回起動すると、このエラーが発生します。

解決方法1: プロセスを終了する

現在のポートを使用しているプロセスを終了します。

lsof -i :<ポート番号>
kill -9 <プロセスID>

原因2: 他のプロセスがポートを占有している

別のアプリケーションが指定されたポートを使用している場合、競合が発生します。

解決方法2: 別のポートを使用する

サーバーのポート番号を変更します。

// ポート番号を3001に変更
const PORT = 3001;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

原因3: ポートの解放が遅延している

サーバーが停止後もポートが解放されていない場合、このエラーが発生します。

解決方法3: ポートの解放を待つ

時間を置いてからサーバーを再起動します。または、強制的にプロセスを終了します。

原因4: Windowsのプロセス管理の問題

Windows環境では、一部のプロセスがポートを解放しないことがあります。

解決方法4: コマンドプロンプトでプロセスを確認

以下のコマンドを使用してプロセスを特定し、終了します。

netstat -ano | findstr :<ポート番号>
taskkill /PID <プロセスID> /F

原因5: 同じポートを使用する複数のインスタンス

クラスター化や複数のサーバーインスタンスで競合が発生する場合があります。

解決方法5: ポート番号を動的に割り当てる

動的なポート割り当てを設定します。

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

原因6: プロセスがバックグラウンドで実行されている

バックグラウンドで動作しているプロセスがポートを占有することがあります。

解決方法6: pm2などのプロセスマネージャーを確認

バックグラウンドで動作しているプロセスを停止します。

pm2 list
pm2 stop <プロセス名>

原因7: ファイアウォールやネットワーク設定の問題

一部のネットワーク設定が特定のポートの使用を制限することがあります。

解決方法7: ファイアウォール設定を確認

ポートが開放されているかを確認します。

sudo ufw allow <ポート番号>/tcp

原因8: Dockerコンテナ内での競合

Dockerコンテナが同じポートを使用する場合にエラーが発生します。

解決方法8: ポートマッピングを変更

Dockerのポート設定を変更します。

docker run -p 3001:3000 <イメージ名>

原因9: OSがポートをリサイクルしていない

ソケットの再利用が適切に設定されていない場合があります。

解決方法9: ソケットの再利用を有効化

サーバー設定で「SO_REUSEADDR」を有効にします。

const server = require('http').createServer(app);
server.listen(3000, '0.0.0.0', () => {
  console.log('Server is running');
});
server.on('error', (err) => {
  console.error(err);
});

原因10: 複数のネットワークインターフェース

異なるネットワークインターフェース間でポート競合が発生する場合があります。

解決方法10: 明示的にIPを指定

ローカルホストや特定のIPアドレスを指定してサーバーを起動します。

app.listen(3000, '127.0.0.1', () => {
  console.log('Server running on localhost:3000');
});

まとめ

「Error: listen EADDRINUSE: address already in use」は、主にポート競合が原因で発生します。プロセスの確認やポート番号の変更などの手順を実行して、問題を解決できます。