主机无法访问dockerized应用程序上的API

时间:2018-12-03 14:06:14

标签: python-3.x api docker windows-10 ubuntu-18.04

我在Windows 10 64位计算机上使用Docker桌面(版本2.0.0.0-win81(29211))。我还按照以下指南激活了WSL,并安装并配置了Ubuntu 18.04.1:Docker on Windows and WSL

现在关闭我的问题:我正在运行并使用开箱即用的docker容器,mongodb和neo4j db。很好。

我最近决定使用Flask对自己的Python3.6应用程序进行docker化。此应用程序具有API,并且将在不久的将来部署在云服务器上。

如果我在本地运行该应用程序,则可以通过邮递员(GET,POST)与api进行交互,并且一切正常/正常。

所以我在暴露端口的情况下构建了映像,在发布端口时部署了docker容器并启动了它(下面给出的代码),看起来不错:

CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                                      NAMES
fba51f89f31a        m002_production:latest   "python communicatio…"   About an hour ago   Up About an hour    0.0.0.0:5000->5000/tcp, 0.0.0.0:5003->5003/tcp             M002_gi
f36cd69cf5ce        mongo:4.1.5              "docker-entrypoint.s…"   4 hours ago         Up 4 hours          0.0.0.0:27017->27017/tcp                                   M002_testmongo
ae8d610bbcd8        neo4j:3.0                "/docker-entrypoint.…"   4 hours ago         Up 4 hours          0.0.0.0:7474->7474/tcp, 7473/tcp, 0.0.0.0:7687->7687/tcp   M002_testneo4j

然后我检查应用程序是否以'docker logs M002_gi'正确启动:

Path given:  /config/
 * Serving Flask app "M002" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

它确实按预期启动。但是,到达API无效。我现在所知道的:

  • 端口绑定和已发布的端口似乎正常。
  • 根据docker inspect,所有容器都具有相同的网络设置,我甚至对整个docker inspect进行了比较,以找到解决方案的线索-没有线索。
  • 如果我通过docker exec -it ...输入docker容器,并使用curl检查所有网络功能:一切正常。
  • 另外两个容器(neo4j和mongodb)也可以从主机PC外部访问。
  • 不是我自己的python应用程序容器。

因此,我肯定会丢失一些东西,但我不知道这是什么。 Dockerfile:

FROM python:3.6-alpine
MAINTAINER default "addanaddress@here.com"
# We copy just the requirements.txt first to leverage Docker cache
COPY ./requirements.txt /M002/requirements.txt
RUN apk add --update build-base
EXPOSE 5000/tcp
EXPOSE 5003/tcp
# holds externally mounted volumes
VOLUME ["/M002/data", "/M002/config"]
WORKDIR /M002
RUN pip install -r requirements.txt
COPY . /M002
# this is the main executable
ENTRYPOINT [ "python" ]
# this is the default argument for the executable
CMD [ "communication_handler.py", "/config/" ]

我的docker build命令:

docker build -t m002_production:latest .

我的docker run命令:

docker run --name M002_test -p 5000:5000 -p 5003:5003 -v /c/Users/MyName/MyConfig:/M002/config -v /c/Users/MyName/MyConfig:/config --rm -d m002_production:latest

当我针对本地版本(端口5001上没有docker)运行api查询时,我的查询结果:Successful query 我针对dockerized版本(暴露并发布的端口5000)运行它时的查询结果:Failed query

当我从Hyper卷曲时:

curl localhost:5000
curl: (52) Empty reply from server

我期望的是

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>

到目前为止,我尝试过的事情(除了我在互联网上找到的所有内容):

  • 调用FLASK与其他IP(包括0.0.0.0,localhost和 与docker系统和其他各种端口兼容的IP。
  • 将不同的docker bridge网络分配给容器(默认和MProject)。我确保将容器分配给网络是正确的。

我的docker网络ls:

NETWORK ID          NAME                DRIVER              SCOPE
a41825cf65ca        MProject            bridge              local
60aae249fa11        bridge              bridge              local
3f5cb1334815        host                host                local
b6746f907725        none                null                local

到目前为止我的发现摘要:

  • curl @ host-> mongodb @ docker:有效
  • curl @ host-> neo4j @ docker:有效
  • postman @ host-> mongodb @ docker:有效
  • postman @ host-> neo4j @ docker:有效
  • mypythonapplication @ host(未经dockerized)-> mongodb @ docker:有效
  • mypythonapplication @ host(未经dockerized)-> neo4j @ docker:有效
  • curl / postman @ host-> mypythonapplication @ host(未docker化):有效

    如果我使用以下命令登录:docker exec mypythonapplication -it sh,然后使用 卷曲或ping或任何我确切得到我期望的响应的东西,所以:

  • mypythonapplication @ docker-> mongodb @ docker:有效
  • mypythonapplication @ docker-> neo4j @ docker:有效

  • curl @ host-> mypythonapplication @ docker:不起作用

  • postman @ host-> mypythonapplication @ docker:不起作用

谢谢您的提示!

1 个答案:

答案 0 :(得分:2)

您的问题很可能是由于烧瓶使用“错误的” IP引起的: Running on http://127.0.0.1:5000/

flask的默认设置是仅在本地主机上侦听,在这种情况下,它将是容器内的本地主机 ,而不是Docker主机的本地主机。

尝试像这样启动烧瓶: flask.run(host='0.0.0.0', port=5000)