【问题标题】:API on dockerized application not reachable from host无法从主机访问 dockerized 应用程序上的 API
【发布时间】:2019-05-04 20:22:10
【问题描述】:

我在 Windows 10 64 位机器上使用 Docker Desktop(版本 2.0.0.0-win81 (29211))。我还按照本指南激活了 WSL 并安装和配置了 Ubuntu 18.04.1:Docker on Windows and WSL

现在解决我的问题:我正在运行和使用开箱即用的 docker 容器、mongodb 和 neo4j db。他们很好。

我最近决定使用 Flask 对我自己的 Python3.6 应用程序进行 dockerize。这个应用有一个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)可以从主机外部访问。
  • 我自己的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 运行命令:

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

当我对本地版本运行 api 查询时我的查询结果(端口 5001 上没有 docker):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(未 dockerized):工作

    如果我使用以下命令登录:docker exec mypythonapplication -it sh,然后使用 curl 或 ping 或任何我得到的正是我期望的响应,所以:

  • mypythonapplication@docker -> mongodb@docker : 工作
  • mypythonapplication@docker -> neo4j@docker : 工作

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

  • postman@host -> mypythonapplication@docker: 不工作

感谢您的任何提示!

【问题讨论】:

  • 你如何测试neo4j和mongo?您对这些容器使用哪个主机名?还有localhost?
  • 是的,我也将 localhost 用于 mongodb 和 neo4j。我可以使用来自 Ubuntu 的 curl 查询这些服务,或者从 Postman 查询,或者从我的 dockerized python 应用程序运行的 alpine 容器中查询,以及使用 neo4j 的浏览器界面。如果我在没有 docker 的情况下运行我的 python 应用程序,我可以从那里与两个 docker 容器进行交互。完全没有问题。
  • 你试过在调试模式下运行它吗?我希望这更像是您的 python 容器在某个地方(依赖关系、与其他容器的连接、任何东西)内部出错的情况,因为您得到一个 empty reply 而不是连接被拒绝或类似的情况,如果它在指定主机+端口

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


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 2020-01-12
    • 2018-04-05
    • 2019-09-16
    • 2016-12-10
    • 2023-02-01
    • 1970-01-01
    相关资源
    最近更新 更多