ポートと localhost
💡 学習ガイド:
npm run devを実行してターミナルにhttp://localhost:5173と表示されたとき、「localhostとは何か?」「5173は何を表しているのか?」「なぜEADDRINUSEエラーが出るのか」と考えたことはありませんか?この章では、開発で毎日目にする yet 深く掘り下げることの少ないこれらの概念を徹底的に解説します。
始める前に、2 つの基礎知識を復習しておくことをお勧めします:
- ネットワークの基礎:IP アドレスや HTTP の概念がよく分からない場合は、コンピュータ基礎 - ネットワーク通信を先にご覧ください。
- ターミナルの基礎:コマンドラインターミナルに慣れていない場合は、コマンドラインとシェルスクリプトを先にご覧ください。
0. はじめに:毎日見る localhost:5173 って一体何?
$ npm run dev
> vite
准备就绪...GET /index.html),然后把对应的文件内容返回给你。すべての開発者の日常にこの行が出力されます:
➜ Local: http://localhost:5173/しかし、この短い 1 行にいくつの重要な概念が詰め込まれているか考えたことはありますか?
- http:// → 通信プロトコル(どんな言語で話すか)
- localhost → 宛先アドレス(誰を探すか)
- :5173 → ポート番号(見つけた後、どのドアをノックするか)
この 3 つを理解すれば、開発環境のネットワーク問題の 90% を解決できます。一つずつ分解していきましょう。
1. ポートとは何か?(IP はビル、ポートは部屋番号)
1.1 直感的な例え
サーバーを 1 つのビルと想像してください:
- IP アドレス(例:
192.168.1.100)はビルの住所——「どのビルに行くか」を教えます。 - ポート番号(例:
:80)はビルの中の部屋番号——「どの部屋に入るか」を教えます。
1 つのビルには、レストラン(80 号室)、カフェ(443 号室)、オフィス(22 号室)を同時に置くことができます。同様に、1 台のコンピュータでは、ウェブサーバー、データベース、SSH サービスを同時に実行し、それぞれが異なるポートを使用できます。
👇 試してみよう: 下の「部屋番号」をクリックして、異なるポートへの接続をシミュレートしてください。ポートが「開いている」(プログラムがリッスンしている)場合と「閉じている」場合で何が起こるか観察してください。
1.2 ポート番号の範囲
ポート番号は 0–65535 の整数です(合計 65,536 個)。これらのポートは 3 つの範囲に分かれています:
| 範囲 | 値 | 用途 | 例 |
|---|---|---|---|
| システムポート | 0 – 1023 | 標準プロトコル用に予約。一般ユーザーは自由に使用できない | 80 (HTTP)、443 (HTTPS)、22 (SSH) |
| 登録ポート | 1024 – 49151 | 一般的なアプリケーションの登録用 | 3306 (MySQL)、5432 (PostgreSQL)、6379 (Redis) |
| 動的ポート | 49152 – 65535 | オペレーティングシステムが一時的に割り当て | ブラウザがリクエストを送る際、システムがランダムに送信元ポートを割り当てる |
なぜ開発サーバーは 3000、5173、8080 を好むのか?これらはすべて「登録ポート」の範囲内にあり、管理者権限なしでリッスンでき、システムサービスと競合しにくいからです。
1.3 開発でよく使われるポート番号早見表
👇 試してみよう: ポート番号またはサービス名を入力して検索。任意の行をクリックして使用例を展開してください。
80HTTP网页访问(未加密)安全443HTTPS网页访问(加密)安全22SSH安全远程登录注意21FTP文件传输敏感3306MySQLMySQL 数据库敏感5432PostgreSQLPostgreSQL 数据库敏感27017MongoDBMongoDB 数据库敏感6379RedisRedis 缓存敏感3000Node/ReactNode.js / React 开发服务器安全5173ViteVite 开发服务器安全8080通用 HTTPHTTP 备用端口 / 代理安全8000Django/PythonDjango / Python HTTP 服务安全5000FlaskFlask 开发服务器安全4200AngularAngular 开发服务器安全53DNS域名解析注意25SMTP邮件发送注意2. localhost とは何か?(自分自身を見つける)
2.1 「ループバック」の核心概念
localhost は特別なドメイン名で、常に自分自身のコンピュータを指します。
ブラウザで http://localhost:3000 と入力したとき、次のようなことが起こります:
- ブラウザが OS に問い合わせる:「
localhostの IP は何?」 - OS が即座に答える:「
127.0.0.1」(ネットワークで DNS を検索する必要なし) - パケットが
127.0.0.1に送られるが、実際にはマシンを離れない - OS が「ループバックインターフェース」を通じてパケットを折り返す
- ポート 3000 でリッスンしているプログラムがリクエストを受信し、レスポンスを返す
全体のプロセスでネットワークケーブルもルーターもインターネットも経由しません。
👇 試してみよう: 「リクエストを送信」をクリックして、データパケットの完全な旅を観察してください。その後、下の「エイリアスカード」をクリックして、localhost のいくつかの書き方とその違いを理解してください。
localhost→ 127.0.0.1127.0.0.1→ 127.0.0.1::1→ ::10.0.0.0→ 0.0.0.0/etc/hosts 文件里的映射。浏览器看到 localhost 时,直接解析为 127.0.0.1,不会去问 DNS 服务器。 2.2 localhost vs 127.0.0.1 vs 0.0.0.0
これら 3 つの概念はよく混同されますが、意味は全く異なります:
| 表記 | 意味 | 誰がアクセスできるか |
|---|---|---|
localhost / 127.0.0.1 | ループバックアドレス、ローカルマシンのみ | 自分のコンピュータのみ |
0.0.0.0 | すべてのネットワークインターフェースでリッスン | ローカルマシン + LAN 内の他のデバイス |
192.168.x.x | LAN IP | LAN 内のデバイス |
実際のシナリオ:
# 自分だけがアクセスできる(安全、開発に適している)
npm run dev -- --host localhost
# スマホでもアクセスできる(モバイルデバッグに適している)
npm run dev -- --host 0.0.0.0多くのフレームワーク(Vite、Next.js など)はデフォルトで
localhostをリッスンするため、スマホが同じ WiFi に接続していても開発サーバーにアクセスできません。スマホでデバッグしたい場合は、--hostフラグを追加するだけです。
3. ポートの競合:最もよくある開発環境の問題
3.1 なぜ競合が起こるのか?
1 つのポートは同時に 1 つのプログラムしかリッスンできない。 これは 1 つの部屋に 1 つの世帯しか住めないのと同じです。
同じポートで 2 つ目のサービスを起動しようとすると、このおなじみのエラーが表示されます:
Error: listen EADDRINUSE :::3000平たく言えば:「3000 号室は既に誰かが住んでいます。入れません!」
よくある競合シナリオ:
- 前回の開発サーバーが正しくシャットダウンされず、バックグラウンドでまだ動いている
- 2 つの異なるプロジェクトが同じデフォルトポートを使用している
- 何らかのシステムサービスが使用したいポートを既に占有している
👇 試してみよう: 下のシミュレーターでサービスを複数回起動してみてください。ポートが競合したとき、「直接起動」と「スマート起動」がどう異なる対応をするか比較してください。
:5173🟢 RunningEADDRINUSE 错误,说明这个端口已经被占了。要么杀掉旧进程,要么换个端口。 3.2 トラブルシューティングと解決
ポートの競合に遭遇した場合、トラブルシューティングの手順は非常に一定です:
macOS / Linux:
# ステップ 1:ポート 3000 を誰が使っているか確認
lsof -i :3000
# ステップ 2:PID を取得したら、強制終了
kill -9 <PID>Windows:
# ステップ 1:ポート 3000 を誰が使っているか確認
netstat -ano | findstr :3000
# ステップ 2:プロセスを終了
taskkill /PID <PID> /F多くのモダンフレームワーク(Vite、Create React App など)は、ポートの競合を検出すると「別のポートに切り替えますか?」と自動的に尋ねます。しかし、基盤となる原理を理解していれば、フレームワークでは対応できない難しい問題により早く対処できます。
4. 開発における「同一生成元ポリシー」と CORS
4.1 「生成元」とは何か?
ブラウザには同一生成元ポリシー(Same-Origin Policy)と呼ばれるセキュリティメカニズムがあります:プロトコル、ドメイン、ポートの 3 つがすべて一致している場合のみ、「同一生成元」と見なされます。
| URL A | URL B | 同一生成元? | 理由 |
|---|---|---|---|
http://localhost:5173 | http://localhost:5173/about | ✅ 同一生成元 | プロトコル、ドメイン、ポートがすべて同じ |
http://localhost:5173 | http://localhost:3000 | ❌ 異なる生成元 | ポートが異なる(5173 vs 3000) |
http://localhost:5173 | https://localhost:5173 | ❌ 異なる生成元 | プロトコルが異なる(http vs https) |
4.2 なぜフロントエンドとバックエンドの分離で必ず CORS に遭遇するのか?
プロジェクトのアーキテクチャが次のようになっている場合:
フロントエンド (Vite) → http://localhost:5173
バックエンド (Express) → http://localhost:3000フロントエンドのページは :5173 から読み込まれ、fetch('/api/users') で :3000 の API をリクエストします——ポートが異なるため、クロスオリジン制限がトリガーされます!
2 つの一般的な解決策:
解決策 1:バックエンドで CORS を設定
// Express バックエンド
app.use(cors({ origin: 'http://localhost:5173' }))解決策 2:フロントエンドでプロキシを設定(推奨)
// vite.config.js
export default {
server: {
proxy: {
'/api': 'http://localhost:3000'
}
}
}プロキシの仕組み:Vite 開発サーバーがリクエストを「転送」します。ブラウザは :5173 と通信している(同一生成元)と思っていますが、実際には Vite が背後で密かにリクエストを :3000 に転送しています。
5. 実践トラブルシューティング:3 つの最も一般的な問題
👇 試してみよう: 遭遇した問題を選択し、手順に従ってトラブルシューティングしてください。各ステップで「実行」をクリックして出力を確認できます。
lsof -i :30006. 用語対照表
| 英語用語 | 日本語訳 | 説明 |
|---|---|---|
| Port | ポート | 0–65535 の数字で、同じマシン上の異なるネットワークサービスを区別する。各サービスはポートを「リッスン」し、クライアントの接続を待機する。 |
| localhost | ローカルホスト | 常にローカルマシン(127.0.0.1)を指す特別なドメイン名。インターネットに接続せずにローカルマシン上で実行中のサービスにアクセスするために使用。 |
| Loopback Interface | ループバックインターフェース | オペレーティングシステムの仮想ネットワークインターフェース。127.0.0.1 宛てのパケットはマシンを離れず、このインターフェースを通じて「折り返される」。 |
| EADDRINUSE | アドレスは既に使用中 | Node.js / OS からのエラーで、リッスンしようとしているポートが既に他のプログラムに占有されていることを示す。 |
| CORS | クロスオリジンリソース共有 | ブラウザのセキュリティメカニズム。フロントエンドページが異なる生成元(プロトコル/ドメイン/ポートが異なる)の API にリクエストしようとする際、バックエンドが明示的に許可する必要がある。 |
| Same-Origin Policy | 同一生成元ポリシー | ブラウザセキュリティの基盤:同一プロトコル、同一ドメイン、同一ポートのリクエストのみ自由な通信を許可し、クロスオリジンのデータ読み取りをブロックする。 |
| Proxy | プロキシ | 開発環境において、プロキシサーバーがブラウザに代わってバックエンドにリクエストを転送し、ブラウザの同一生成元制限を回避する。 |
| 0.0.0.0 | すべてのインターフェース | サービスが 0.0.0.0 をリッスンする場合、すべてのネットワークインターフェース(ローカルマシン、LAN など)からの接続を受け入れることを示す。 |
| Well-known Ports | ウェルノウンポート | ポート 0–1023 の総称。HTTP (80)、HTTPS (443)、SSH (22) などの標準プロトコル用に予約されている。 |
| PID | プロセス ID | OS が実行中の各プログラムに割り当てる一意の番号。プロセスの管理と終了に使用。 |
| lsof | オープンファイルの一覧表示 | macOS/Linux コマンド。特定のポートを使用しているプロセスを確認するのに使用(lsof -i :ポート番号)。 |
| HMR | ホットモジュールリプレイスメント | 開発サーバーの機能:コードを変更するとブラウザが自動更新され、手動でのページリフレッシュが不要。内部的に WebSocket 通知を使用。 |
まとめ
ポートと localhost は開発環境において最も基礎的で、最も頻繁に遭遇する概念です:
- ポート = マシン上の異なるサービスを区別する「部屋番号」(0–65535)
- localhost = 「自分自身を見つける」特別なアドレス(127.0.0.1)、データはマシンを出ない
- ポートの競合の本質は「1 つの部屋番号には 1 つの看板しか掲げられない」
- CORSの本質は「ポートが異なる = 異なる生成元」であり、CORS またはプロキシで解決が必要
この 4 つのポイントを覚えておけば、開発環境で遭遇するほとんどのネットワーク問題の原因を迅速に特定できます。