Dockerポートバインディング完全ガイド|-pと-Pの違い・セキュリティまで
第2章の 2-6 で -p 8080:80 の基本は学びました。第5章の締めくくりとして、ポートバインディングを実務で安全に使うための細かい書式をまとめます。セキュリティに関わる話も多いので、本番運用前に一度目を通してほしい内容です。
💡 この記事のゴール
①
②
③
④ コンテナ間通信では
⑤ iptables / ファイアウォールとの関係
①
-p の全フォーマット(IP指定・範囲・UDP)②
-P(大文字)の自動割当③
127.0.0.1: 指定によるセキュリティ強化④ コンテナ間通信では
-p 不要(ありがちな誤解)⑤ iptables / ファイアウォールとの関係
目次
- 復習:-p の役割
- -p の全フォーマット
- -P(大文字):自動ポート割当
docker portで確認する- セキュリティ強化:
127.0.0.1指定 - コンテナ同士は
-p不要 - ファイアウォール・iptables との関係
- よくあるつまずき
- まとめ
1. 復習:-p の役割
-p(publish)はホスト側の指定ポートへ来たトラフィックをコンテナ内のポートに転送するルールを作ります。Docker は内部で iptables の NAT ルールを挿入してこれを実現しています。
【
-p 8080:80 で何が起きているか】🌐 クライアント
:8080
━▶
🖥️ ホスト
iptables NAT
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番が世界に公開されていた…という事故が本当に起きます。公開したくないポートは最初から
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 の設定で行う。
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)で登場する重要概念です。
基礎編はここまで。応用として 5-5 ネットワークドライバの種類で、bridge以外の選択肢(host / none / overlay / macvlan)を俯瞰します。複数ホストでコンテナを動かす段階(第10章 Swarm)で登場する重要概念です。
参考リンク
- Published ports(Docker公式) —
-p/-Pの詳細仕様。 - Packet filtering and firewalls(Docker公式) — Docker と iptables・ufw の関係。



コメント