为什么在Dockerfile中使用EXPOSE-因为您仍然可以绑定到所有端口


23

我可以docker run -p 3000:3000 image EXPOSE使用容器中的该端口(请参见下文)。如果是这样,那为什么还要麻烦将EXPOSE放入Dockerfile中呢?它仅用于与图像用户通信吗?因为我不知道EXPOSE端口是否可以绑定的功能性原因。


这些步骤显示了我绑定到容器中的端口,尽管事实并非如此

$ cat Dockerfile
FROM alpine
RUN apk add nodejs npm vim
COPY webserver /webserver
CMD [ "node", "/webserver/index.js" ]


$ docker build .
Sending build context to Docker daemon  1.931MB
Step 1/4 : FROM alpine
 ---> 11cd0b38bc3c
Step 2/4 : RUN apk add nodejs npm vim
 ---> Using cache
 ---> 4270f8bdb201
Step 3/4 : COPY webserver /webserver
 ---> Using cache
 ---> 67f4cda61ff0
Step 4/4 : CMD [ "node", "/webserver/index.js" ]
 ---> Using cache
 ---> 1df8f9024b85
Successfully built 1df8f9024b85


$ curl localhost:4400
curl: (7) Failed to connect to localhost port 4400: Connection refused


$ docker run -d -p 4400:3000 1df8f9024b85
7d0e6c56f8ad8827fe72830a30c1aac96821104b8ea111291ca39e6536aad8fd


$ curl localhost:4400
Hello World!


$

Answers:


29

Docker的EXPOSE文档解决了这一特定问题:

EXPOSE指令实际上并未发布端口。它充当构建映像的人员与运行容器的人员之间的一种文档类型,有关打算发布哪些端口的信息。要在运行容器时实际发布端口,请使用-p标记on docker run发布和映射一个或多个端口,或者使用-P标记发布所有公开的端口并将它们映射到高阶端口。

请注意最后一句话,如果公开了多个端口,则-P可以避免-p在命令行上设置多个端口。


“文档”采用图像元数据的形式。除了对-P标志有用之外,其他实用程序还可以查询正在运行的容器以获取此元数据,这在代理中很有用,这些代理使用这些暴露的端口作为默认值来动态更新其转发规则。
BMitch

@BMitch绝对,我觉得这对OP没有帮助,但可以随时对其进行编辑
。– Tensibai

EXPOSE是文档
井上智文

4

这样做是出于自动化的考虑。您可以运行一个通用命令docker run -P来启动容器,而Dockerfile本身用于指定哪个容器公开哪个端口。如果您要处理通过管道构建的数十个或数百个容器,这将非常有用。从阶段到阶段通过管道将未包含在Dockerfile中的外部细节与容器一起传递是相当困难的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.