如何在 docker 文件中发布端口

Posted

技术标签:

【中文标题】如何在 docker 文件中发布端口【英文标题】:How to publish ports in docker files 【发布时间】:2015-12-20 19:36:02 【问题描述】:

我需要将主机上的端口映射到容器上的端口。我可以通过运行带有-p 选项的"docker run" 命令来实现这一点。我如何通过Dockerfile 实现这一目标? 使用以下给出"deprecated error"

EXPOSE 80:8080

我还能如何通过 dockerfile 将暴露的端口公开?

【问题讨论】:

【参考方案1】:

    EXPOSE Dockerfile 上的端口列表。

    运行docker run -d -P --name app_name app_image_name

    前面的步骤成功后,

    运行docker port app_name,它将显示如下输出:

    80/tcp -> 0.0.0.0:32769 443/tcp -> 0.0.0.0:32768

【讨论】:

【参考方案2】:

exposepublish 是有区别的。

expose表示在容器端开放端口,publish表示在Docker主机上对外开放。

例如,如果您的 docker run 命令有 -p 80:8080,它会在容器上公开端口 8080,并在主机上发布端口 80。

您只能在 Dockerfile 中真正公开端口,如果您希望灵活地发布端口,则需要使用 -P 选项和 docker run。像这样:

docker run -P your_app

【讨论】:

这里要提到的另一件事是发布发生在随机端口:-P, --publish-all Publish all exposed ports to **random** ports。要查看确切的映射,请使用 docker port CONTAINER_NAME【参考方案3】:

你可以做的是EXPOSEDockerfile 上的端口列表,然后运行命令docker run -P your_app 以发布 Dockerfile 上公开的所有端口

【讨论】:

【参考方案4】:

你不能。在 docker 主机上发布哪些端口严格来说应该由本地管理员做出决定,而不是由他们试图运行的镜像决定;这将是 (a) 一个安全问题(嘿,我刚刚打开了对您系统的 ssh 访问权限!)和 (b) 容易发生故障(我的 webserver 容器无法绑定到端口 80,因为我已经在运行服务器端口 80)。

如果您想避免冗长的docker run 命令行,请考虑使用docker-compose 之类的东西来自动化该过程。然后,您可以通过 docker-compose 配置如下:

mywebserver:
  image: myname/mywebserver
  ports:
    - 80:8080

然后一个简单的docker-compose up 将启动您的容器,容器端口 8080 绑定到主机端口 80。

2017 年 3 月 11 日更新

回应薇拉的评论:

使用docker-compose 无助于解决端口冲突问题。端口冲突问题是图像不能指定主机端口绑定的一个原因。我只是提供docker-compose 作为具有多个端口绑定的长docker run 命令行的替代方案。端口冲突问题可能允许容器对您的主机执行拒绝服务攻击:例如,如果容器在您的主机(或另一个容器)上的 Apache 服务器之前启动并绑定到端口 80,那么您刚刚失去了网络服务。

关于安全问题:如果图像能够指定主机端口绑定,则容器可能会在您不知情的情况下打开对容器的访问。如果内核中的命名空间功能无法完全隔离容器,允许远程用户访问主机上的容器,即使您完全信任隔离,它也会让您面临主机妥协的可能性如果该容器被用于非法目的,则可能引发法律问题。无论哪种情况,这都是个坏主意。

【讨论】:

如何使用 docker-compose 解决端口冲突的可能性?另外你能不能稍微解释一下安全问题?

以上是关于如何在 docker 文件中发布端口的主要内容,如果未能解决你的问题,请参考以下文章

使用 docker 时如何避免“端口冲突”?

如何让两个 dockerized 应用程序在给定端口上通信?

如何在docker容器中开启两个端口映射

如何在 Docker 上发布 UDP 端口?

如何在没有端口映射的情况下将 docker 容器的 ip 和端口暴露给外部 docker 主机?

docker 在不同的端口上运行 mongo 映像