5.4 Dockerポートバインディング完全ガイド|-pと-Pの違い・セキュリティまで

【第2章】イメージとコンテナの基本操作

Dockerポートバインディング完全ガイド|-p-Pの違い・セキュリティまで

第2章の 2-6 で -p 8080:80 の基本は学びました。第5章の締めくくりとして、ポートバインディングを実務で安全に使うための細かい書式をまとめます。セキュリティに関わる話も多いので、本番運用前に一度目を通してほしい内容です。

💡 この記事のゴール
-p の全フォーマット(IP指定・範囲・UDP)
-P(大文字)の自動割当
127.0.0.1: 指定によるセキュリティ強化
④ コンテナ間通信では -p 不要(ありがちな誤解)
⑤ iptables / ファイアウォールとの関係

目次

  1. 復習:-p の役割
  2. -p の全フォーマット
  3. -P(大文字):自動ポート割当
  4. docker port で確認する
  5. セキュリティ強化:127.0.0.1 指定
  6. コンテナ同士は -p 不要
  7. ファイアウォール・iptables との関係
  8. よくあるつまずき
  9. まとめ

1. 復習:-p の役割

-p(publish)はホスト側の指定ポートへ来たトラフィックをコンテナ内のポートに転送するルールを作ります。Docker は内部で iptables の NAT ルールを挿入してこれを実現しています。

-p 8080:80 で何が起きているか】
🌐 クライアント
:8080

━▶
🖥️ ホスト
iptables NAT
8080 → 80

━▶
📦 コンテナ
:80 で受信


2. -p の全フォーマット

# 書式
-p [ホストIP:]ホストポート:コンテナポート[/プロトコル]

# 例
-p 8080:80                           # 全IFのホスト8080 → コンテナ80(TCP)
-p 127.0.0.1:8080:80                 # ループバックのみ(外部不可)
-p 80:80                             # ホストも80を使う
-p 443:443                           # HTTPS
-p 53:53/udp                         # UDP(DNSなど)
-p 8080-8090:80-90                   # 範囲マッピング
-p 192.168.1.10:8080:80              # 特定のホストIPだけで受ける
書き方 意味 実務での使いどころ
-p 8080:80 全IF(0.0.0.0)→ コンテナ80/tcp 開発用ローカル公開
-p 127.0.0.1:8080:80 ホストのループバックのみ LAN・外からアクセスさせない場合
-p 192.168.1.10:8080:80 特定NIC経由のみ 複数IPのあるサーバで公開先を絞る
-p 53:53/udp UDPプロトコル指定 DNS・VPN・QUIC
-p 80:80/tcp -p 53:53/udp 両方 TCP/UDP両方扱うサービス
-p 8080-8090:80-90 ポート範囲 連番ポートを使うアプリ
💡 プロトコル省略時は TCP
-p 8080:80-p 8080:80/tcp と同じ意味。UDPを使いたい場合は明示的に /udp を書く必要があります。DNSリゾルバ・VPNサーバ・ゲームサーバなどUDPで通信するサービスで注意。

3. -P(大文字):自動ポート割当

大文字の -P は、イメージが EXPOSE 宣言している全ポートを、ホストの空いているポートに自動で割り当てます。

$ docker run -d --name web -P nginx
a7b8c9d0...

$ docker port web
80/tcp -> 0.0.0.0:32768
80/tcp -> [::]:32768

# ブラウザで http://localhost:32768 で見える

ホストポートが被ったときの事故を防げる反面、URLが毎回変わるのでユーザー公開には不向き。テスト・CI向きです。


docker port で確認する

# 特定コンテナの全マッピング
$ docker port web
80/tcp -> 0.0.0.0:8080

# 特定ポートだけ
$ docker port web 80
0.0.0.0:8080

# docker ps でも確認できる(PORTS 列)
$ docker ps --format 'table {{.Names}}\t{{.Ports}}'
NAMES    PORTS
web      0.0.0.0:8080->80/tcp

5. セキュリティ強化:127.0.0.1 指定

本番で最も大事な一文:外部に公開したくないポートは、必ずホストIP 127.0.0.1 指定で bind する。

書き方 アクセスできる範囲 評価
-p 5432:5432 LAN内の他マシン・インターネット(※ファイアウォール設定次第) ⚠️ DBを直接世界に晒す
-p 127.0.0.1:5432:5432 同じホスト上のプロセスのみ ✅ 安全(DBの定番)
⚠️ Docker はホストのUFW / firewalld を迂回する
Linux で UFW や firewalld を有効にしていても、Docker は iptables を直接操作するためファイアウォールルールを貫通してポートを公開します。「UFW を設定したから安全」と油断すると、5432番が世界に公開されていた…という事故が本当に起きます。公開したくないポートは最初から -p 127.0.0.1:... で明示的にローカル限定にしましょう。

6. コンテナ同士は -p 不要

ありがちな誤解:「アプリから DB につなぐので、DB コンテナには -p 5432:5432 を付ける」。これは間違いです。

【-p の要・不要】
-p が必要:ホスト外からコンテナにアクセス
ブラウザ → nginx / 外部APIクライアント → アプリ

-p は不要:コンテナ同士で完結する通信
アプリ → DB / アプリ → redis / アプリ → メッセージキュー
同じカスタムブリッジにいれば名前解決 + 全ポート到達可(5-1/5-2)

docker network create app-net

# DB は -p なし(外部公開しない)
docker run -d --name db --network app-net \
  -e POSTGRES_PASSWORD=secret postgres:16

# アプリは -p あり(ブラウザから叩く)
docker run -d --name app --network app-net -p 3000:3000 \
  -e DATABASE_URL="postgres://postgres:secret@db:5432/postgres" \
  myapp
💡 原則「最小公開」
外から触られる必要がないサービスは -p を付けないのが安全。DB・メッセージキュー・内部APIなどはカスタムブリッジ内通信だけで完結します。

7. ファイアウォール・iptables との関係

Dockerは起動するとiptables の DOCKER チェーンに自動でルールを入れます。-p するたびに DNAT ルールが追加され、ポート転送が実現されています。

# DNAT ルールの確認(要 root)
$ sudo iptables -t nat -L DOCKER -n
Chain DOCKER (2 references)
target     prot opt source    destination
DNAT       tcp  --  0.0.0.0/0 0.0.0.0/0  tcp dpt:8080 to:172.18.0.2:80

Docker の iptables 操作を止めたい場合

自前で iptables ルールを管理したい上級者向け:/etc/docker/daemon.json"iptables": false を設定。ただしポート転送・コンテナ間分離などの機能が全部自分の責任になるので、通常は触りません。

⚠️ ホストOSのファイアウォールと Docker の関係
Linux: Docker が iptables を直接操作するため、ufw/firewalld の設定は Docker 公開ポートには効かない(前述の注意点)。
Windows/macOS: Docker Desktop のVM境界があるため、ホスト OS のファイアウォールは VM 全体に対してかかる。細かい制御は Docker Desktop の設定で行う。

8. よくあるつまずき

症状 原因 対処
port is already allocated ホスト側のそのポートを他プロセスが使用中 lsof -i:8080 で確認、別ポートに変更
ブラウザで接続できない -p を付け忘れた/IP指定が狭すぎる docker port で公開状況を確認
UDPサービスに繋がらない /udp を忘れた -p 53:53/udp のように明示
DB が外からアクセスできてしまう 127.0.0.1 を指定しなかった+UFW無視問題 -p 127.0.0.1:5432:5432 で限定、または -p 自体を外す
同じポートを複数コンテナに割当てようとした 1ポートに1コンテナが原則 異なるホストポートに分ける、またはリバースプロキシで振り分け
Mac/Win で iptables 出力が空 コンテナは VM 内、iptables もVM 内 Docker Desktop VM 内で確認する必要あり(通常は気にしない)

9. まとめ

押さえどころ 内容
書式 -p [ホストIP:]ホストポート:コンテナポート[/プロトコル]
TCP / UDP 省略 = TCP、/udp で UDP
ローカル限定 -p 127.0.0.1:... を必ず使う(DB など)
UFW/firewalld は効かない Docker が iptables 直操作、明示的に 127.0.0.1 で守る
コンテナ間通信は -p 不要 同じカスタムブリッジ内なら全ポート通る
自動割当 -P で EXPOSE 全ポートをランダム公開
✅ 次のステップ
基礎編はここまで。応用として 5-5 ネットワークドライバの種類で、bridge以外の選択肢(host / none / overlay / macvlan)を俯瞰します。複数ホストでコンテナを動かす段階(第10章 Swarm)で登場する重要概念です。

参考リンク


Dockerの基礎を動画で体系的に学びませんか?

実務で使う基礎だけを3時間に凝縮。環境構築から丁寧に解説しています。

Udemy Docker入門講座 クーポン割引で講座を見る →

コメント

タイトルとURLをコピーしました