Open1
Docker環境で学ぶ 0.0.0.0 と 127.0.0.1 の違いと確認方法
Docker上で開発をしていると、「ポートは開いているはずなのにブラウザからアクセスできない」という状況に遭遇することがあります。
原因のひとつとして「0.0.0.0 で待ち受けているか」「127.0.0.1 で待ち受けているか」の違いがあります。
本記事では /proc/net/tcp※ を例に、実際の確認方法を整理します。
(※ コマンドだけで手軽に確認したかったため採用しました)
環境
pc:MacBook Pro(2019)
os:macos Sequoia
Python:3.13.1
構成
.
├── docker-compose.yml
├── express
│ ├── Dockerfile
│ ├── package-lock.json
│ ├── package.json
│ └── server.js
├── README
└── vite
├── Dockerfile
├── index.html
├── package-lock.json
└── package.json
各種ファイル
docker-compose.yml
version: "3.9"
services:
express:
build: ./express
ports:
- "3000:3000"
vite-nohost:
build: ./vite
command: ["npm","run","dev"]
ports:
- "5173:5173"
vite-host:
build: ./vite
command: ["npm","run","dev","--","--host","0.0.0.0"]
ports:
- "5174:5173"
express
express/Dockerfile
FROM node:20
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY server.js ./
EXPOSE 3000
CMD ["node","server.js"]
express/package.json(package-lock.json)
{
"name": "express-min",
"version": "1.0.0",
"private": true,
"main": "server.js",
"scripts": { "start": "node server.js" },
"dependencies": { "express": "^4.19.2" }
}
express/server.js
const express = require("express");
const app = express();
const PORT = 3000;
app.get("/", (_req, res) => res.send("Hello from Express!"));
app.listen(PORT);
vite
- vite は開発環境で利用する検証用サーバー
vite/Dockerfile
FROM node:20-bullseye
WORKDIR /app
COPY package.json index.html /app/
RUN npm install
# CMDは compose.yml 側で指定(--host 有無を切り替える)
vite
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Vite Host Check</title></head>
<body>
<h1>Hello from Vite !</h1>
</body>
</html>
vite/package.json(package-lock.json)
{
"name": "vite-host-check",
"private": true,
"scripts": {
"dev": "vite --port 5173"
},
"devDependencies": {
"vite": "^5.2.0"
}
}
検証コマンド
まずはサービスを稼働します。
$ docker compose up -d
/proc/net/tcp の見方
- docker ps の PORTS はホスト側の公開設定。コンテナ内の bind 先(0.0.0.0 / 127.0.0.1)は分からないため、
/proc/net/tcpで確認します。
ポート番号は16進数で表記される
- 0BB8 (hex) = 3000 (dec) → Express サーバーのポート
- 1435 (hex) = 5173 (dec) → Vite dev サーバーのポート
(進数変換についての記事です↓)
アドレス部はリトルエンディアン(逆順に読んで変換)
- 00000000 → 0.0.0.0(全IF待受)
- 0100007F → 127.0.0.1(ローカル専用)
例:
- 00000000:PORT = 0.0.0.0:PORT(外部からアクセス可)
- 0100007F:PORT = 127.0.0.1:PORT(コンテナ内からのみアクセス可)
実際の確認
Express(3000番)
$ docker exec -it host-check_express_1 \
sh -lc "grep -E ':(0BB8)' /proc/net/tcp /proc/net/tcp6 || true"
/proc/net/tcp6: 0: 00000000000000000000000000000000:0BB8 ...
→ 000...000:0BB8 は IPv6 全IF (:: :3000)。
実質 0.0.0.0:3000 → 全IF待受(外部アクセス可)
$ curl -i http://localhost:3000
HTTP/1.1 200 OK ...
Hello from Express!
→ OK
Vite(--host を付けない場合):
$ docker exec -it host-check_vite-nohost_1 \
sh -lc "grep -E ':(1435)' /proc/net/tcp /proc/net/tcp6 || true"
/proc/net/tcp: 0: 0100007F:1435 ...
→ 0100007F:1435 = 127.0.0.1:5173。
→ コンテナ内だけで有効
$ curl -i http://localhost:5173
curl: (52) Empty reply from server
→ NG
Vite(--host 0.0.0.0 を指定した場合):
$ docker exec -it host-check_vite-host_1 \
sh -lc "grep -E ':(1435)' /proc/net/tcp /proc/net/tcp6 || true"
/proc/net/tcp: 1: 00000000:1435 ...
→ 00000000:1435 = 0.0.0.0:5173。
→ 外部からもアクセス可能
$ curl -i http://localhost:5174
HTTP/1.1 200 OK ...
→ OK
- Express はデフォルトで 0.0.0.0 にバインドされる(外部OK)
- Vite はデフォルトで 127.0.0.1 にバインドされる(内部のみ)
-
--host 0.0.0.0を付けると Vite もコンテナ外からもアクセス可になる -
/proc/net/tcpを読むことで「実際にどこへバインドされているか」が正しく確認できる