我正在尝试使用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中公开端口有什么意义,如果它仍然会被发布?是否需要首先公开端口,不以后发布它?实际上,我想在创建映像时指定我将在Dockerfile中使用的所有端口,然后再不用再次打扰它们,只需运行它们:
$ docker run -d an_image
这可能吗?
答案 0 :(得分:576)
基本上,您有三种选择:
EXPOSE
也未指定-p
EXPOSE
EXPOSE
和-p
1)如果您既未指定EXPOSE
也未指定-p
,则只能从 容器本身访问容器中的服务。
2)如果EXPOSE
是一个端口,则无法从Docker外部访问容器中的服务,而是从其他Docker容器中访问。所以这对于容器间通信很有用。
3)如果你EXPOSE
和-p
是一个端口,容器中的服务可以从任何地方访问,甚至可以在Docker之外访问。
两者分开的原因是恕我直言,因为:
documentation明确指出:
EXPOSE
指令公开了在链接中使用的端口。
它还指出如何link containers,这主要是我所谈到的容器间通信。
PS:如果您执行-p
但不EXPOSE
,则Docker会执行隐式EXPOSE
。这是因为如果一个端口对公众开放,它也会自动向其他Docker容器开放。因此-p
包含EXPOSE
。这就是为什么我没有把它作为第四种情况列在上面。
答案 1 :(得分:80)
EXPOSE
是记录 --publish
(或-p
)是一种映射 主机端口到正在运行的容器端口的方式请注意以下内容:
EXPOSE
与Dockerfiles
(记录)--publish
与docker run ...
(执行/运行时)公开和发布端口
在Docker网络中,有两种不同的机制直接涉及网络端口:公开和发布端口。这适用于默认桥接网络和用户定义的桥接网络。
使用Dockerfile中的
EXPOSE
关键字或--expose
标志将端口暴露给docker run。 公开端口是记录使用哪些端口的方法,但实际上并未映射或打开任何端口。公开端口是可选的。您使用
--publish
或--publish-all
标记向docker run
发布端口。这告诉Docker在容器的网络接口上打开哪些端口。发布端口时,除非您在运行时指定要在主机上映射到的端口,否则它将映射到主机上的可用高阶端口(高于30000
)。 在构建映像时(在Dockerfile中)无法指定要在主机上映射到的端口,因为无法保证端口在运行映像的主机上可用强>
此外,
EXPOSE
...
EXPOSE
指令实际上并未发布端口。 它可以作为构建图像的人和运行容器的人之间的一种文档,关于哪些端口要发布。
EXPOSE
/ --publish
时的服务访问权限:在@Golo Roden's回答时声明::
&#34;如果您未指定其中任何一项,将无法从容器内部的任何位置访问容器中的服务。&#34;
在撰写答案时可能就是这种情况,但现在看来即使您不使用EXPOSE
或--publish
, host
和同一网络中的其他containers
将能够访问您可能在该容器内启动的服务。
我使用了以下Dockerfile
。基本上,我从ubuntu开始并安装一个小型的Web服务器:
FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd
我build
图片为&#34; testexpose&#34;和run
一个新容器:
docker run --rm -it testexpose bash
在容器内部,我启动了一些mini-httpd
:
root@fb8f7dd1322d:/# mini_httpd -p 80
root@fb8f7dd1322d:/# mini_httpd -p 8080
root@fb8f7dd1322d:/# mini_httpd -p 8090
然后,我可以使用主机或其他容器中的curl
来获取mini-httpd
的主页。
答案 2 :(得分:7)
EXPOSE
允许您定义私有(容器)和公共(主机)端口,以便在映像构建时公开容器运行的时间。
公共端口是可选的,如果没有指定公共端口,则docker将在主机上选择一个随机端口,以在Dockerfile上公开指定的容器端口。
一个好的实践是不指定公共端口,因为它每个主机只限制一个容器(第二个容器将抛出已经在使用的端口)。
您可以使用-p
中的docker run
来控制公开端口可以连接的公共端口。
无论如何,如果您不使用EXPOSE
或-p
,则不会暴露任何端口。
如果您始终在-p
使用docker run
,则不需要EXPOSE
,但如果您使用EXPOSE
,则docker run
命令可能会更简单,{{ 1}}如果您不关心将在主机上公开的端口,或者您确定只加载一个容器,则非常有用。
答案 3 :(得分:3)
大多数人使用docker compose with networks。 documentation州:
Docker网络功能支持创建网络而无需在网络中公开端口,详细信息请参阅此功能的概述。
这意味着如果您使用网络进行容器之间的通信,则无需担心暴露端口。
答案 4 :(得分:3)
您可以使用Dockerfile中的EXPOSE关键字或 - 将标志暴露给docker run。公开端口是一种记录哪种方式 使用端口,但实际上并不映射或打开任何端口。公开港口 是可选的。
答案 5 :(得分:0)
Dockerfile EXPOSE与发布
曝光
在编写Dockerfile时,指令EXPOSE告诉Docker运行中的容器在特定的网络端口上进行侦听。这是一种端口映射文档,可在发布端口时使用。
曝光[/...]
您还可以在docker run命令中指定此名称,例如:
docker run --expose = 1234 my_app
但是EXPOSE不允许通过定义的端口与同一网络外部的容器或主机进行通信。为此,您需要发布端口。
发布端口并将其映射到主机
使用docker run命令在容器网络外部发布容器的端口并将其映射到主机的端口时,可以使用多个标志。这些是-p和-P标志,它们在您要发布一个端口还是所有端口方面有所不同。
要在运行容器时实际发布端口,请在docker run上使用-p标志发布并映射一个或多个端口,或使用-P标志发布所有公开的端口并将其映射到高阶端口。 — Docker文档:EXPOSE
docker run -p 80:80 / tcp -p 80:80 / udp my_app
在上面的示例中,-p标志后面的第一个数字是主机端口,第二个是容器端口。
要使用EXPOSE发布您在Dockerfile中定义的所有端口并将其绑定到主机,可以使用-P标志。
docker run -P my_app
答案 6 :(得分:-3)
EXPOSE用于映射本地端口容器端口 即:如果您在
之类的docker文件中指定暴露 EXPOSE 8090
它将做什么,它将本地主机端口8090映射到容器端口8090