简短的回答:
EXPOSE是一种记录的方式
——publish(或-p)用于将主机端口映射到正在运行的容器端口
注意如下:
EXPOSE与Dockerfiles相关(文档化)
——publish与docker run相关…(执行/运行时)
Exposing and publishing ports
In Docker networking, there are two different mechanisms that directly involve network ports: exposing and publishing ports. This applies to the default bridge network and user-defined bridge networks.
You expose ports using the EXPOSE keyword in the Dockerfile or the --expose flag to docker run. Exposing ports is a way of documenting which ports are used, but does not actually map or open any ports. Exposing ports is optional.
You publish ports using the --publish or --publish-all flag to docker run. This tells Docker which ports to open on the container’s network interface. When a port is published, it is mapped to an available high-order port (higher than 30000) on the host machine, unless you specify the port to map to on the host machine at runtime. You cannot specify the port to map to on the host machine when you build the image (in the Dockerfile), because there is no way to guarantee that the port will be available on the host machine where you run the image.
from: Docker container networking
Update October 2019: the above piece of text is no longer in the docs but an archived version is here: docs.docker.com/v17.09/engine/userguide/networking/#exposing-and-publishing-ports
Maybe the current documentation is the below:
Published ports
By default, when you create a container, it does not publish any of its ports to the outside world. To make a port available to services outside of Docker, or to Docker containers which are not connected to the container's network, use the --publish or -p flag. This creates a firewall rule which maps a container port to a port on the Docker host.
and can be found here: docs.docker.com/config/containers/container-networking/#published-ports
同时,
暴露
...EXPOSE指令实际上并不发布端口。它作为构建映像的人员和运行容器的人员之间的一种文档类型,用于发布关于哪些端口的信息。
来自:Dockerfile引用
没有定义EXPOSE /——publish时的服务访问:
在@Golo Roden的回答中,它指出::
“如果你不指定其中任何一个,容器中的服务将不能从容器本身之外的任何地方访问。”
也许在编写答案时就是这样,但现在看来,即使您不使用EXPOSE或——publish,同一网络的主机和其他容器也能够访问您可能在该容器中启动的服务。
如何测试:
我使用了下面的Dockerfile。基本上,我从ubuntu开始,安装一个小型web服务器:
FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd
我将映像构建为“testexpose”,并运行一个新的容器:
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的主页。
进一步的阅读
Ivan Pepelnjak关于这个主题的非常详细的文章:
暴露的港口
发表的港口