我正在试验DockerFiles,我想我理解其中的大部分逻辑。然而,在这种情况下,我看不出“公开”和“发布”端口之间的区别。
我第一次看到的所有教程都包含Dockerfile中的EXPOSE
命令:
...
EXPOSE 8080
...
然后,他们从该Dockerfile构建一个映像:
$ docker build -t an_image - < Dockerfile
然后在运行镜像时发布与上面相同的端口:
$ docker run -d -p 8080 an_image
或使用发布所有端口
$ docker run -d -P an_image
如果某个端口无论如何都要发布,那么在Dockerfile中公开它有什么意义呢?有没有必要先公开一个端口,然后“不”再发布它?实际上,我希望指定在创建映像时将在Docker文件中使用的所有端口,然后不再使用它们,只需使用以下命令运行它们:
$ docker run -d an_image
这个是可能的吗?
7条答案
按热度按时间i2byvkas1#
基本上,您有三(四)个选项:
1.既不指定
EXPOSE
,也不指定-p
1.仅指定
EXPOSE
1.指定
EXPOSE
和-p
1.仅指定隐式执行
EXPOSE
的-p
1.如果不指定
EXPOSE
,也不指定-p
,则容器中的服务只能从容器本身的内部访问。1.如果您
EXPOSE
一个端口,则容器中的服务不能从Docker外部访问,而是从其他Docker容器内部访问。因此,这对于集装箱之间的通信是有好处的。1.如果您的
EXPOSE
和-p
是一个端口,则容器中的服务可以从任何地方访问,即使是在Docker之外。1.如果您做了
-p
,但不做EXPOSE
,Docker会隐式做EXPOSE
。这是因为如果一个港口对公众开放,它也会自动对其他Docker容器开放。因此,-p
包括EXPOSE
。这实际上与3)相同。两者分离的原因是因为:
该文档明确规定:
EXPOSE
指令公开链接内使用的端口。它还为您指明了如何使用link containers,这基本上就是我所说的容器间通信。
svujldwt2#
简答:
EXPOSE
是一种记录的方式--publish
(或-p
)是Map一个主机端口到一个正在运行的容器端口的一种方式请注意以下内容:
EXPOSE
与Dockerfiles
相关(文档中)--publish
与docker run ...
(执行/运行时)相关暴露和发布端口
在Docker网络中,有两种不同的机制直接涉及网络端口:暴露端口和发布端口。这适用于默认网桥网络和用户定义的网桥网络。
EXPOSE
关键字或--expose
标志公开端口以停靠运行。暴露端口是一种记录使用了哪些端口的方式,但不会实际Map或打开任何端口。暴露端口是可选的。--publish
或--publish-all
标志将端口发布到docker run
。这将告诉Docker在容器的网络接口上打开哪些端口。发布端口时,它将Map到主机上可用的高阶端口(高于30000
),除非您在运行时在主机上指定要Map到的端口。您无法在构建镜像时指定要Map到宿主机上的端口(在Dockerfile中),因为无法保证该端口在您运行镜像的宿主机上可用。出发地:码头集装箱网络
2019年10月更新:文档中不再有上述文本,但存档版本在此处:docs.docker.com/v17.09/engine/userguide/networking/#exposing-and-publishing-ports
也许当前的文档如下所示:
发布的端口
默认情况下,当您创建容器时,它不会向外部世界发布其任何端口。要使端口可用于Docker外部的服务或未连接到容器网络的Docker容器,请使用
--publish
或-p
标志。这将创建将容器端口Map到Docker主机上的端口的防火墙规则。并可在此处找到:docs.docker.com/config/containers/container-networking/#published-ports
另外,
曝光
...
EXPOSE
指令实际上并不发布端口。它的作用是构建镜像的人和运行容器的人之间的一种文档,关于打算发布哪些端口。发件人:Dockerfile参考
未定义
EXPOSE
/--publish
时的服务访问:在@Golo Roden的回答中说::
也许在编写答案时是这样的,但现在看来,即使您不使用
EXPOSE
或--publish
,同一网络的host
和其他containers
也将能够访问您可能在该容器内启动的服务。如何测试:
我使用了以下
Dockerfile
。基本上,我从ubuntu开始,然后安装一个小型Web服务器:I
build
图像为“Testexposure”,run
为新容器,带有:在容器中,我启动了几个
mini-httpd
示例:然后,我可以从主机或其他容器使用
curl
来获取mini-httpd
的主页。进一步阅读
Ivan Pepelnjak关于这个主题的非常详细的文章:
ffvjumwh3#
请参阅官方文档参考:https://docs.docker.com/engine/reference/builder/#expose
EXPOSE
允许您定义私有(容器)和公共(主机)端口,以便在映像构建时暴露容器运行时*如果**您使用-P
运行容器。公共端口和协议是可选的,如果不指定公共端口,docker会在host上随机选择一个端口,在Dockerfile上暴露指定的容器端口。
一个不错的做法是不要指定公共端口,因为它只限制每个主机一个容器(第二个容器将抛出一个已在使用的端口)。
您可以在
docker run
中使用-p
来控制公开的容器端口将连接到哪个公共端口。无论如何,如果您不使用
EXPOSE
(在docker run上使用-P
),也不使用-p
,则不会暴露任何端口。如果您总是在
docker run
上使用-p
,则不需要EXPOSE
,但如果您使用EXPOSE
,则docker run
命令可能会更简单,如果您不关心主机上将公开哪个端口,或者如果您确定只加载一个容器,则EXPOSE
可能会很有用。iyfamqjs4#
您可以使用Dockerfile中的expose关键字或--expose标志公开端口以运行docker。公开端口是记录使用了哪些端口的一种方式,但实际上并不Map或打开任何端口。暴露端口是可选的。
来源:GitHub提交
tv6aics15#
大多数人使用对接式作文与网络。文档说明:
Docker网络功能支持创建网络,无需暴露网络内的端口,详细信息请参见该功能的概述)。
这意味着,如果您使用网络在容器之间进行通信,则不需要担心暴露端口。
8hhllhi26#
Exposed关键字让所有者通知其他人容器主要使用哪些端口。
您可以发布任何端口,即使您没有在Exposure中指定端口。
例如,我们使用nginx图像创建了一个Dockerfile,该文件公开了端口1234
并建造它
Docker Build-t端口测试。
并使用发布80端口到本地主机:80来运行它
Docker Run-p 80:80端口测试
当您转到Localhost:80时,您将看到nginx默认页面。Nginx default page
r6l8ljro7#
Expose用于Map本地端口容器端口ie:如果您在如下所示的docker文件中指定expose
EXPOSE 8090
它将执行什么操作将本地主机端口8090Map到容器端口8090