我的主机上有一个守护进程在某个端口上运行(即8008),我的代码通常通过联系localhost:8008与守护进程交互。
我现在已将我的代码集装箱化但尚未成为守护程序。 如何将容器上的localhost:8008转发到运行容器的主机上的localhost:8008(以及守护进程)。
以下是主机上的netstat -tlnp
。我希望容器在主机上将localhost:2009转发到localhost:2009
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2009 0.0.0.0:* LISTEN 22547/ssh
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 ::1:2009 :::* LISTEN 22547/ssh
答案 0 :(得分:20)
所以你需要考虑这个问题的方法是Docker容器有自己的网络堆栈(除非你明确告诉它与--net=host
共享主机的堆栈)。这意味着当与主机端口链接时,端口需要在docker容器内内部以及外部(documentation)暴露。容器上公开的端口需要显式绑定到主机端口(-p xxxx:yyyy
命令中使用docker run
)或隐式(使用Dockerfile中的EXPOSE
并使用-P
在命令行上),就像它说here。如果您的Dockerfile不包含EXPOSE 8008
,或者您未在--expose 8008
命令中指定docker run
,则即使您使用了容器,您的容器也无法与外界通信 -p 8008:8008
命令中的docker run
!
因此,要在容器上与tcp / 8008链接的主机上获取tcp / 8008,您需要在Dockerfile中使用EXPOSE 8008
(然后在容器中docker build
)或--expose 8008
docker run command
。此外,您需要隐式使用-P
或-p 8008:8008
将显式的容器端口显式链接到主机端口。执行此操作的示例docker run
命令可能如下所示:
docker run -it --expose 8008 -p 8008:8008 myContainer
很容易记住,在-p 8008:8008
命令行选项中,此操作的顺序为-p HOST_PORT:CONTAINER_PORT
。此外,请不要忘记,除非您在主机上的iptables 中取消阻止此端口,否则您将无法从Internet上的其他计算机SSH连接到您的容器。我总是忘记这一点并浪费半小时才记得我忘记了iptables -A INPUT ...
主机上那个特定的tcp端口。但是你应该能够在没有iptables规则的情况下从你的主机SSH到容器,因为它使用环回来进行本地连接。祝你好运!
答案 1 :(得分:0)
我不确定你是否可以使用泊坞窗的设置来做到这一点。 如果我的立场是正确的,暴露端口不是你想要的。 相反,建立从容器到主机的ssh端口转发可能就是答案。
答案 2 :(得分:0)
在检查了答案并进行了一些调查之后,我相信有2种方法可以做到,而这2种仅在Linux环境中有效。
第一个是这篇帖子How to access host port from docker container
在--network=host
或docker run
时,应将第二个设置为docker container create
。在这种情况下,您的码头工人将使用与Mac中相同的网络接口。
但是,以上两种方式都不能在Mac中使用,因此我认为在Mac环境中无法从容器转发到主机。如果我错了请纠正我。
答案 3 :(得分:0)
TL;DR:对于 MacOS 或 Windows 主机,使用特殊的主机名 host.docker.internal
而不是 localhost
容器内要访问的任何位置{{1} } 在主机上。
完整回答:主机运行的是MacOS还是Windows?在 Docker Desktop 的文档中隐藏着 there is no docker0 bridge on MacOS 和 there is no docker0 bridge on Windows 的事实。显然这就是造成这种情况的原因。在这两种情况下,解决方法(紧随其后,在标题为“用例和解决方法”的小节中)是使用特殊主机名 localhost
代替 host.docker.internal
容器内您要访问的任何位置 { {1}} 在主机上。
所以在 OP 的情况下,应该使用 localhost
而不是 localhost
。请注意,这是对容器内运行的应用程序代码的代码或配置更改。无需在容器配置中提及端口。 不要尝试在 host.docker.internal:8008
命令行中使用 localhost:8008
或 -p
。这不仅没有必要,而且如果您希望容器连接的主机应用程序已经在该端口上侦听,您的容器将无法启动。
这显然是 some techniques for achieving this 仅适用于 Linux 主机的原因。如果您通读那里给出的答案,您会发现 Docker 在 2017-2018 年的时间范围内多次更改了解决此问题的方法。我不知道他们何时最终将 --expose
确定为特殊主机名。如果他们再次改变主意,请前往我首先链接到的 Docker 桌面文档的已知限制部分(希望)找到新的解决方案。但希望他们能解决这个问题。
答案 4 :(得分:-3)
docker run -d --name <NAME OF YOUR CONTAINER> -p 8008:8008 <YOUR IMAGE>
这会将容器中的端口8008
发布到您主机上的8008
。