-P
https://docs.docker.jp/engine/reference/run.html#expose-p 'ホストポート:コンテナポート'
port:'ホストポート:コンテナポート'
)EXPOSE 命令だけは、実際にはポートを 公開publish しません。これは、どのポートを公開する意図なのかという、イメージの作者とコンテナ実行者の両者に対し、ある種のドキュメントとして機能します。コンテナの実行時に実際にポートを公開するには、 docker run で -p フラグを使い、公開用のポートと割り当てる( マップmap する)ポートを指定します
-- https://docs.docker.jp/engine/reference/builder.html#expose
EXPOSE命令はホスト側のポートを開けません。
ホスト側のポートを開けるには、docker run
ならp
/P
オプションで明示的に指定します。
(ホスト側で既に稼働しているポート番号をホスト側のポート番号に指定することはできません。)
httpd
の例を記載します。
ホストのポート8000
番を開けます。
コンテナはポート80番
でリッスンすることがhttpd:latest
のEXPOSE
で明記されています[^port][port2]。
$ sudo docker run -p '8000:80' httpd:latest
[^port2]:-p xx:xx
のホスト側ポート番号に既に使用されているポート番号を指定することはできません。例えばホストでWebサーバが80番で起動している場合に-p 80:80
を指定してコンテナを起動するとポートのpublishに失敗します。
-P, --publish-all Publish all exposed ports to random ports -- docker run --help
対応するホスト側のポートはDockerが自動で割り当てます。
-p, --publish list Publish a container's port(s) to the host -- docker run --help
Dockerfileでports
プロパティを指定します。
version: '3'
services:
app:
image: httpd:latest
volumes:
- ./html:/var/www/html
ports:
- "8000:80"
httpd:latest
のEXPOSE
で80
が指定されています。203.0.113.100
でコンテナを公開する場合の動作を確かめます。
$ docker run -d httpd:latest
上記コマンドではhttp://203.0.113.100
にアクセスできません[^curl]。
以下のとおりホスト
のポート番号80
が閉じていることがわかります。
$ nmap 127.0.0.1 -Pn -p 80
...
PORT STATE SERVICE
80/tcp closed http
...
[^curl]: コンテナ内では、httpdがポート80番でリッスンしています。docker exec
でコンテナにログインして$ curl -v 127.0.0.1
でHTMLドキュメントを取得できます。
http://203.0.113.100
にアクセスできるようにするには-p
オプションを使ってpublish
する必要があります。
ホストのポート80番をコンテナのポート80番に対応させてpublish
します。
$ docker run -d -p '80:80' httpd:latest
ホスト
でポート番号80の状態を確認します。ホスト
のポート番号80が開いています。
$ nmap 127.0.0.1 -Pn -p 80
...
PORT STATE SERVICE
80/tcp open http
...
docker run
のp
/P
オプション、docker compose
のports
プロパティでホスト
のポートをpublish
すると、Dockerデーモンによってiptables
が変更されます。
$ docker run -d httpd:latest
$ iptables -L
....
Chain DOCKER (3 references)
target prot opt source destination
...
$ docker run -d -p '80:80' httpd:latest
$ iptables -L -n
...
Chain DOCKER (4 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 172.18.0.2 tcp dpt:80
...
Dockerはネットワーク172.18.0.2
の80
番をオープンします。
ホスト
の80
番をオープンするわけではありません。
$ docker run -d --net sample2 -p 80 --name web-httpd httpd
p
オプションがxx:xx
ではなくxx
と単独でしていされた場合はコンテナ
のポート番号を表しますsample2
の80
番を開けます^exposeホストのポート番号は以下のように調べることができます。
$ docker port web-httpd 80
0.0.0.0:49157
:::49157
$ iptables -L -n
Chain DOCKER (4 references)
...
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 172.18.0.2 tcp dpt:80
ACCEPT tcp -- 0.0.0.0/0 172.19.0.2 tcp dpt:80
...
49157を開けるわけではありません。
https://www.fe-siken.com/kakomon/01_aki/q34.html
$ docker port {{container}} {{port}}
コンテナのポート番号がホストのどのポート番号に割り当てられているかを確認します。