第26章:ポート公開は最小限:公開するのは“入口だけ”🚪🌐
この章では「どのポートを外に出して、どれを絶対に外に出さないか」を、迷わず決められる設計の型にします😄🧠 (結論:外に見せるのは “入口” だけ。DBとかRedisは中に閉じ込める🍱🔐)
1) まずイメージ:ポート公開=“外に穴を開ける”🕳️😱
コンテナの中でアプリが 3000 番で待ち受けていても、それだけでは外(PCの外)からは基本来れません。
でも ports:(または -p)で公開すると、ホスト側に穴が開いて外から到達できる状態になります🌍💥
しかも大事ポイント👇 ポート公開はデフォルトだと “外の世界にも” 開きがちです⚠️(LANや状況によってはインターネット側まで…) なので「公開は最小限」が超重要です🛡️ (Docker Documentation)
2) “最小公開”の黄金ルール 7つ🏆🔒
ルール1:公開していいのは基本「Web/API」だけ🧑💻➡️🌐
- ブラウザやアプリがアクセスする入口(例:APIサーバー)だけ公開✅
- 入口が1つなら、守る場所も1つで済む🎯✨
ルール2:DB/Redis/Queue は外に出さない🙅♂️🗄️
- DBを公開すると「見つけられる→殴られる(総当たり)→設定ミスで死亡」コースが早いです😇💣
- アプリからだけDBに行けるのが正解🙆♀️🍱
ルール3:開発中は “localhost バインド” が基本🔥
127.0.0.1 で縛ると 自分のPCからしか触れないので、事故が激減します🧯✨
(Docker Documentation)
ルール4:0.0.0.0 は「全開放」になりがち😱
Composeの ports: は IPを書かないと全インターフェース(0.0.0.0)にバインドしやすいです⚠️
(matsuand.github.io)
ルール5:Docker Desktop は “ポートのデフォルト挙動” を設定できる🧩
Docker Desktop には、ポートバインドを デフォルトで localhost に寄せる / 強制する設定があります🔧 (事故を減らす系の神設定🙏) (Docker Documentation)
ルール6:EXPOSE は「公開」じゃない📌
Dockerfile の EXPOSE は「このアプリはこのポート使うよ」という目印で、ホストに公開はしません👀
(Docker Documentation)
ルール7:「公開してから守る」より「公開しない」が最強🛡️✨
ファイアウォールや認証より前に、まず穴を開けないのが最強コスパです💪😄 (特に個人開発はこれが効く!)
3) Composeで“安全な公開”を作る(ここ超重要)💥🧠
A. 一番よくある危険パターン😇
「とりあえず動けばOK」でこうしがち👇
services:
api:
ports:
- "3000:3000"
これ、IP指定がないので **0.0.0.0 にバインド(全開放寄り)**になりやすいです⚠️ (matsuand.github.io)
B. 開発での鉄板:localhost に縛る🔒✨
services:
api:
ports:
- "127.0.0.1:3000:3000"
これなら基本「自分のPCからだけ」アクセスできます👍 (Dockerのポート公開は“外にも開く”のがデフォルトで危ないよ、って公式も強めに言ってます) (Docker Documentation)
C. “長い書き方”で安全を明示する(おすすめ)🧾✨
services:
api:
ports:
- name: web
target: 3000
published: "3000"
host_ip: 127.0.0.1
protocol: tcp
host_ip: 127.0.0.1 を明示できるので、レビューしやすいです👀✅
(matsuand.github.io)
4) ハンズオン:APIだけ公開、DBは完全に内部専用🍱🔐
例:api + db の compose(DBは公開しない)
services:
api:
build: .
ports:
- "127.0.0.1:3000:3000"
environment:
DATABASE_URL: "postgres://app:app@db:5432/appdb"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: appdb
# ports: は “書かない” ←これがポイント!
ポイント解説🧠✨
apiだけportsで入口を作る🚪dbは portsなし=ホストから触れない🧊api→db:5432は 内部ネットワークでつながる(公開いらない)🍱
5) “公開しすぎ事故”ミニ演習😇💥(超おすすめ)
演習1:わざとDBを公開してみる(危険を体感)🧪
db にこれを足す👇
db:
ports:
- "5432:5432"
そしてPowerShellで確認👇(外から到達できる穴が開いてるか)
Test-NetConnection 127.0.0.1 -Port 5432
通ったら「穴あいてる!」です🕳️😱
演習2:localhost縛りにして被害半径を縮める🔒
db:
ports:
- "127.0.0.1:5432:5432"
演習3:最終形:DBの ports: を消す🗑️✨
これが最強です💪😄 (アプリ経由でしかDBに行けない=守りやすい)
6) “いま何が公開されてる?”確認するコマンド🔍👀
Docker側で見る🐳
- 公開ポートの一覧を見る(Compose)
docker compose ps
→ PORTS 欄に出てるやつが「外に穴あいてる可能性」高いです⚠️
- もっと細かく見る(コンテナ単位)
docker port <container_name>
Windows側で「待ち受け」を見る🪟
Get-NetTCPConnection -State Listen | Sort-Object LocalPort
「思ったより色々待ち受けてる😇」が見えると、設計が一段上がります📈✨
7) よくある詰まりポイント集🧯😵💫
Q1. ブラウザで http://localhost:3000 が開かない😭
-
ポート被り(別アプリが3000使ってる)➡️
publishedを変える -
アプリが
0.0.0.0じゃなく127.0.0.1だけで待ってる(コンテナ内の待受が原因)- コンテナ内はだいたい
0.0.0.0で待ち受けが無難(外への公開はportsで制御)🌐
- コンテナ内はだいたい
Q2. LANの別PC/スマホからアクセスできない🤔📱
- それはむしろ「閉じてる」ので安全寄りです👍
- どうしても必要なときだけ、公開範囲やFW含めて設計(本番の話に近い)に寄せます🔥
Q3. “全部 localhost に縛りたい” を強制したい😤🔒
Docker Desktop に「ポートバインドの挙動」を変える設定があります(localhost デフォルト化 / 強制) 事故が減るので、個人開発だとかなりアリです🙏✨ (Docker Documentation)
8) AI補助(Copilot / Codex)を“安全に使う”コツ🤖🛡️✨
コード生成でポート公開が増殖しがちなので、AIには 公開ポート監査役をやらせるのが強いです😄 (例:GitHub Copilot、OpenAI Codex、Microsoft系の拡張など)
使えるプロンプト例👇
- 「このcompose.ymlで外部公開されるポートを一覧化して、公開の必要性を説明して」
- 「DB/Redisなど“内部専用”にすべきサービスが ports で公開されてないかチェックして」
- 「
0.0.0.0バインドになってるポートがあったら理由と直し方を提案して」
あと超大事⚠️
AIが「とりあえず ports: - "5432:5432"」みたいに言い出したら、“穴を開ける前提”になってる合図です😇💣
まず「公開しなくて済む設計」に戻すのが勝ちです🏆✨
9) まとめ:第26章のセルフ監査チェック✅🔍
- 外に出してるのは Web/API だけ?🚪
- DB/Redis/Queue は
ports:なし?🍱 - 公開が必要でも
127.0.0.1縛りにできてる?🔒 -
portsのIP省略(0.0.0.0寄り)を“うっかり”で使ってない?😇 -
docker compose psで公開ポートを定期的に見てる?👀 -
EXPOSEとportsを混同してない?📌 - 「公開して守る」より「公開しない」を先に検討した?🛡️
次の第27章で、ここに Compose networks(内部ネットワーク) を足して「DBは内部だけで会話する🍱🔐」をさらに強固にします🕸️✨