如何从主机访问Docker容器的Web服务器

70

我正在使用boot2docker 1.3.1版本。

我有一个通过uwsgi --http :8080运行的Docker容器中的Web服务器。

如果我附加到容器,我可以使用lynx http://127.0.0.1:8080浏览网站,因此我知道服务器正在运行。

我使用以下命令运行了我的容器:

$ docker run -itP --expose 8080 uwsgi_app:0.2

它有以下细节:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
5248ad86596d        uwsgi_app:0.2     "bash"              11 minutes ago      Up 11 minutes       0.0.0.0:49159->8080/tcp   cocky_hypatia
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 5248ad86596d
172.17.0.107

我原以为通过访问 http://172.17.0.107:49159 可以从我的主机访问该网站。

但是这行不通。在 Chrome 中我只能看到“连接中”,却没有任何结果。

我做错了什么?


你是在Mac或Windows PC上运行Boot2Docker吗?我会假设是Mac,因为有'$'符号。 - Bryan
9个回答

98

在扩展 Anentropic答案的基础上: boot2docker是Mac和Windows的旧应用程序,docker-machine是新的应用程序。

首先,列出您的机器:

$ docker-machine ls

NAME      ACTIVE   DRIVER       STATE     URL                         SWARM
default   *        virtualbox   Running   tcp://192.168.99.100:2376

然后选择其中一台机器(默认的称为 default),并执行以下操作:

$ docker-machine ip default

192.168.99.100

3
解决了我的Windows问题。 - Zac Grierson
22
这份信息在2016年还准确吗?我运行"docker-machine ls"没有任何结果,尽管"docker ps"显示有正在运行的东西。 - Hakanai
在我的 Mac 上仍然可以工作。没有错误信息?尝试重新安装 https://docs.docker.com/docker-for-mac/ / https://docs.docker.com/docker-for-windows/。旧版本需要评估一些 shell 配置,例如 https://docs.docker.com/machine/get-started/。 - HankCa
1
使用 docker inspect $MY_CONTAINER | grep IPAddress 命令。不要安装任何新东西。 - JellicleCat

38

好的,我太愚蠢了,在boot2docker的文档中找到了答案:https://docs.docker.com/installation/mac/#container-port-redirection

我需要使用boot2docker vm的IP地址,而不是容器的IP地址,即:

$ boot2docker ip
192.168.59.103

我可以从主机上浏览我的站点,网址为http://192.168.59.103:49159/

在主机上,我不需要添加任何路由(route)


1
啊,我没有注意到-P选项。 - Bryan
2
在我的情况下,我使用 run -p 选项反转了端口。 -p 80:5000。这将把容器内部的端口5000映射到本地主机上的端口80。我做了相反的事情。请参阅 https://docs.docker.com/userguide/usingdocker/ - Maxence
2
经过一天的故障排除,这解决了我的问题。 - David
1
boot2docker现已弃用,使用docker-machine代替。 - guijob

20

要查找您容器的 IP 地址,您无需进行任何额外的安装:

docker inspect <container>

这提供了大量的信息。使用grep命令搜索IPAddress


3
OP已经展示了他知道如何使用docker inspect找到IPAddress。他的问题特别涉及到为什么在使用该IP地址时似乎连接失败。 - Ben Collins
1
然而,这是一个与问题标题相匹配的好答案,它帮助了我。 - Rugnar
这个IP地址在boot2docker、Docker Machine、Docker Desktop或者任何非本地Linux主机环境下都无法使用。 - David Maze

7
您可以使用boot2docker端口映射选项-L,如此处所述。
因此,在您的情况下,应该是:
boot2docker ssh -L 0.0.0.0:8080:localhost:8080

然后

docker run -it -p 8080:8080 uwsgi_app:0.2

这样,您就不必使用boot2docker的IP地址:您可以使用localhost或自己的IP地址(并且您的Docker容器可以从外部访问)。


4
构建镜像的命令为:docker build -t {imagename} .
docker build -t api-rest-test .

运行Docker容器的命令为:docker run -dp {本地端口}:{公开端口} 镜像名:标签。
 docker run -dp 8080:8080 api-rest-test:latest

请确保你在使用yourlocalport和exposeport时使用相同的端口号。

然后你就可以通过本地机器上的http://localhost:8080访问你的REST服务了。


4

Boot2docker已经过时,但是在Docker for Windows或Mac上可能仍然会遇到这个问题,即使相同的容器在Linux上可以正常工作。一个症状是尝试访问容器内部服务器上的页面时出现错误“没有发送任何数据”,而不是“无法连接”。

如果是这样,在Win/Mac上可能是因为容器主机有自己的IP地址,而不是像Linux一样是localhost。尝试以IP 0.0.0.0运行Django,表示接受来自所有IP的连接,例如:

python manage.py runserver 0.0.0.0:8000

如果您需要确保服务器仅响应本地请求(例如来自本地代理,如nginx、apache或gunicorn),则可以使用hostname -i返回的主机IP。

并确保您在docker run命令中正确使用了-p端口转发选项

假设一切正常,您应该能够在托管机器上运行的浏览器中通过http://localhost访问您的服务器。


1
如果您想要访问容器而无需“发布”端口(从而更改其编号),可以在这里找到详细步骤。
关键是这一行代码:
sudo route -n add 172.17.0.0/16 172.16.0.11

这将告诉Mac如何路由到VirtualBox VM内的私有网络,Docker容器就在其中。


仅仅添加那个路由对我来说并没有解决问题。我在想这个IP 172.16.0.11 是什么?它应该是我的容器IP吗?我尝试了一下,但也不起作用。 - Anentropic

1

我遇到了同样的问题,我的情况是使用AWS EC2实例。我尝试使用容器IP,但不起作用。然后我使用了AWS主机的实际公共IP作为IP,这样就可以了。


天啊,浪费了这么多时间在这个问题上。不知道这种行为的原因是什么。 - f-z-N

0
如何解决在本地主机浏览器上托管应用程序的问题。
为此,请使用以下命令启动容器,在我的情况下是:
[root@centoslab3 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
1b81d8a0e3e1        centos:baseweb      "/bin/bash"         8 minutes ago       Exited (0) 24 seconds ago                       webtest
[root@centoslab3 ~]# docker run --name=atul -v /root/dockertest:/var/www/html -i -t -p 5000:8000 centos:baseweb /bin/bash

在httpd配置中:
[root@adb28b08c9ed /]# cd /etc/httpd/conf
[root@adb28b08c9ed conf]# ll
total 52
-rw-r--r--. 1 root root 34419 Sep 19 15:16 httpd.conf

编辑监听器中端口为8000的文件,并在Servername下更新容器IP和端口。

重新启动httpd服务,完成操作。

希望这能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接