8080
80 が使えないときに開発サーバーや Tomcat、プロキシが掴みにいくポート。そして、あなたが必要になった瞬間には既に誰かが掴んでいるポート。
自分の環境の行をそのまま実行してください。ポートを掴んでいるプロセス名と、バインドしているアドレスが出ます。たいていはそれだけで答えが分かります。
lsof -nP -iTCP:8080 -sTCP:LISTENポートを掴んでいるもののコマンド名、PID、ユーザー、そしてバインドしているアドレスが出ます。`127.0.0.1:8080` ならループバック限定で、同じ Wi-Fi のスマートフォンから届かないのはまさにそれが理由です。`*:8080` なら全インターフェイス。何も出なければそのポートは本当に空いています。別ユーザーのリスナーには `sudo` を足してください。コマンド列に `Docker` や `com.docker.backend` が出たらコンテナの公開ポートなので、そのプロセスを kill するのではなくコンテナを停止します。
sudo ss -tlnp 'sport = :8080'`-t` で TCP、`-l` で待ち受けのみ、`-n` でポートを数値のまま、`-p` で所有プロセスを `users:(("java",pid=8123,fd=50))` の形で出します。ローカルアドレスの列は丁寧に読んでください。`[::]:8080` は IPv6 のワイルドカードでたいてい IPv4 も受けますが、そこに `0.0.0.0:8080` の行が別に並んでいるなら、IPv4 側は別のプロセスが取っています。`sudo` なしでは自分の所有でないもののプロセス列は空です。
netstat -ano | findstr :8080最後の列が、そのソケットを所有する PID です。`tasklist /FI "PID eq 8123"` で名前に変換してください。`findstr` は部分一致なので、リモートアドレス側の `:8080` にも当たります。何かする前にローカルアドレスの列を確認してください。何も出ないのに bind だけ失敗するなら、次の予約範囲の話です。
netsh interface ipv4 show excludedportrange protocol=tcp8080 に誰も待ち受けていないのに bind が失敗するときに実行してください。Hyper-V、WSL2、Docker Desktop、Windows の NAT サービスは起動時に動的ポートの帯を予約します。その帯がたまたま 8080 を含んでいると、犯人となるプロセスが存在しないまま bind だけが失敗します。一覧に 8080 が入っていたら、掴んでいるホストサービスを再起動するか、どの範囲にも入らないポートへ自分のサーバーを移してください。
`nmap -Pn -p 8080 example.com` は、マシンの外側からそこに到達できるかを答えます。`open` は TCP ハンドシェイクが成立したということ、`closed` はホストがリセットを返した、つまり起動してはいるが誰も待ち受けていない状態、`filtered` はプローブが消えた、つまりファイアウォールが破棄したということです。どれだったかは `--reason` で分かりますし、`-sV` を付ければ応答を取ってサーバーのバナーを報告します。8080 にいるのが忘れていた Tomcat だと判明するのはたいていこれです。スキャンは自分が責任を持つホストにだけ。
| 出ているもの | 意味 |
|---|---|
Error: listen EADDRINUSE: address already in use :::8080 | 別のプロセスが既にそのポートを持っています。`:::8080` という表記は IPv6 のワイルドカードで、多くのシステムでは IPv4 も覆うため、ここにバインドされると両方が塞がります。自分の環境のコマンドで持ち主を特定してください。十中八九、端末から切り離されただけで停止していない、同じサーバーの前回の実行です。 |
Only one usage of each socket address (protocol/network address/port) is normally permitted | 同じことの Windows での言い方で、エラー 10048 です。`netstat` にリスナーが出ないなら、占有ではなく予約です。存在しないプロセスを探し回る前に、上の `netsh` コマンドで除外範囲を確認してください。 |
The server says it started, but another device on the same network gets connection refused | `0.0.0.0` ではなく `127.0.0.1` にバインドしています。最近は意図的にループバックを既定にしたフレームワークが多いので、これはバグではなく設定項目です。`--host 0.0.0.0`、`HOST=0.0.0.0`、あるいは相当するもので変わります。コマンドの出力にあるアドレス列が、どちらを選んだかを教えてくれます。 |
The port frees itself about a minute after the server exits | 接続が残ったまま閉じられたソケットは最大 2 分ほど `TIME_WAIT` に留まり、プログラムが `SO_REUSEADDR` を設定していない限り、その間の新しい bind は拒否されます。待てば直りますし、別のポートで起動しても直ります。kill するものは何もありません。 |
8080 answers, but with something you did not start | たいていはポートを公開したままのコンテナで、`docker ps` に `0.0.0.0:8080->8080/tcp` として出てきます。起動時に上がる Tomcat やプリンタの管理画面といった、インストール済みのサービスのこともあります。自分のマシンに `nmap -sV` を向ければバナーを読んで正体を教えてくれます。 |
IANA は 8080 を TCP・UDP 両方で「HTTP Alternate」を意味する `http-alt` として登録しています。番号自体は割り当て済みで、そこで実際に何が動くかのほうが慣習だという珍しい形です。これほど多くのソフトの既定になった理由は身も蓋もなくて、Unix 系では 1024 未満が特権ポートで、80 にバインドするには root か付与された権限が要るのに対し、8080 はどちらも要らないからです。だから開発者が手で起動するもの——Tomcat の既定コネクタ、Jenkins、Spring Boot、Vite や webpack のプロキシ、Docker が公開する Web コンテナのポート、443 で TLS を終端するリバースプロキシの背後にあるオリジン——の住処になりました。番号が意味するのは平文の HTTP であってそれ以上ではありません。暗号化されませんし、ブラウザにとって特別な意味もなく、`http://host:8080/` はただ番号が珍しいだけの普通の HTTP リクエストです。使うソフトが多いぶん、塞がっている 8080 の正体は不思議な何かではなく自分の別のプロセスであることが圧倒的に多く、下のコマンドが一行でそれを名指しします。
80 から 8080 へ移しても、セキュリティ上の効果はまったくありません。全世界を舐めるスキャナーは 8080 も 80 と同じ頻度で見に来るので、見つかるまでの時間は変わりません。実務上 8080 のほうが危ないのは、そこに載りがちなものの性質です。Tomcat の manager アプリケーション、セットアップウィザードが出たままの Jenkins、Spring Boot の actuator、コンテナのデバッグ UI——どれも外に向ける前提で作られていません。開発サーバーは `127.0.0.1` にバインドしてマシンから出られないようにし、本番に近いものは 8080 をファイアウォールで開けるのではなく、443 で TLS を終端するリバースプロキシ越しに公開してください。どうしても到達させる必要があるなら送信元アドレスで絞り、手前に認証を置くこと。中身は平文だという前提で扱ってください。
どれもブラウザ内で完結します。アップロードは発生しません。
8080 を調べているとき、ついでに確認することになりがちなポートです。
ほぼ権限の問題です。lsof や ss はソケット自体は出しますが、他ユーザーのプロセスは所有者の列を伏せるので、システムアカウントやコンテナランタイム、launchd が起動したサーバーは sudo を付け直すまで持ち主不明のリスナーに見えます。Windows は逆で、netstat には何も出ないのに bind だけ失敗します。これは Hyper-V や WSL2、Docker Desktop が起動時に予約したポート帯に当たっている状態です。
何なのかを先に見てください。取り残された開発サーバーなら問題ありませんが、書き込み中のデータベースは別ですし、他が依存しているシステムサービスも同様です。持ち主がコンテナならコンテナごと停止してください。ホストから見えるプロセスを kill してもランタイムが再起動するだけです。どうしても止められないものなら、自分のサービスを別のポートへ移すほうが早く片付きます。
0.0.0.0 ではなく 127.0.0.1 にバインドしているからです。各ページのコマンドがプロセス名と並べてバインド先アドレスを出しているのはこのためで、ループバックにバインドしたものはファイアウォールの設定に関係なく自分のマシンからしか届きません。最近は意図的にそれを既定にしているフレームワークも多いので、たいていはバグではなくフラグの問題です。すでに 0.0.0.0 なのに届かないなら、次に疑うのはホストのファイアウォールかクラウドのセキュリティグループです。
ほとんどなりません。インターネット全体を舐めるスキャナーはポート範囲を丸ごと走査し続けているので、稼げるのは数時間であって安全ではなく、代わりに関係者全員がその番号を覚える羽目になります。既定ポートを狙う無差別スキャンのログが減るという効果は確かにありますが、それだけです。結果を変えるのは認証と、送信元アドレスを絞ったファイアウォールと、そもそも外に出さないことです。
ポート 8080 でまだ詰まっていますか。ポート一覧をすべて見る。あるいは上に戻って、実際に出たエラー文から追ってください。