API 无法从主机访问 dockerized 应用程序
API on dockerized application not reachable from host
我在 Windows 10 64 位机器上使用 Docker 桌面版(版本 2.0.0.0-win81 (29211))。我还按照本指南激活了 WSL 并安装和配置了 Ubuntu 18.04.1:Docker on Windows and WSL.
现在结束我的问题:我正在 运行 正在使用 docker 开箱即用的容器,一个 mongodb 和一个 neo4j 数据库。他们很好。
我最近决定 docker使用 Flask 调整我自己的 Python3.6 应用程序。此应用程序有一个API,将在不久的将来部署在云服务器上。
如果我 运行 在本地运行应用程序,我可以通过邮递员(GET,POST)与 api 交互,并且一切都按预期的 good/bad 工作.
所以我构建了公开端口的映像,在发布端口的同时部署了 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 检查,所有容器都具有相同的网络设置,我什至 运行 总体上存在差异 docker 检查以找到解决方案的线索 - 那里一点头绪都没有。
- 如果我通过 docker exec -it 进入 docker 容器...并使用 curl 检查所有网络功能:一切正常。
- 另外两个容器(neo4j 和 mongodb)可以从外部访问 a.k.a。主机。
- 我自己的python应用容器没有。
因此我肯定遗漏了一些东西,但我无法弄清楚它是什么。
Docker文件:
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构建命令:
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
当我 运行 它针对 docker 化版本(端口 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>
到目前为止我尝试了什么(除了我在互联网上找到的所有东西):
- 使用其他 IP 调用 FLASK 运行,包括 0.0.0.0、localhost 和
与 docker 系统和各种其他端口兼容的 IP。
- 将不同的 docker 桥接网络分配给容器(默认和 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(未 docker 化)-> mongodb@docker :有效
- mypythonapplication@host(未 dockerized)-> neo4j@docker:有效
curl/postman@host -> mypythonapplication@host(未 dockerized):有效
如果我登录:docker exec mypythonapplication -it sh,然后使用
curl 或 ping 或任何我得到我期望的响应,所以:
- 我的python应用程序@docker -> mongodb@docker:有效
mypythonapplication@docker -> neo4j@docker :有效
curl@host -> mypythonapplication@docker:不起作用
- postman@host -> 我的pythonapplication@docker:不起作用
感谢您的任何提示!
您的问题很可能是由使用 "wrong" IP 的 flask 引起的:
Running on http://127.0.0.1:5000/
flask 的默认设置是仅在本地主机上侦听,在这种情况下,它将是本地主机 在 容器中,而不是 docker 主机的本地主机。
尝试像这样启动烧瓶:
flask.run(host='0.0.0.0', port=5000)
我在 Windows 10 64 位机器上使用 Docker 桌面版(版本 2.0.0.0-win81 (29211))。我还按照本指南激活了 WSL 并安装和配置了 Ubuntu 18.04.1:Docker on Windows and WSL.
现在结束我的问题:我正在 运行 正在使用 docker 开箱即用的容器,一个 mongodb 和一个 neo4j 数据库。他们很好。
我最近决定 docker使用 Flask 调整我自己的 Python3.6 应用程序。此应用程序有一个API,将在不久的将来部署在云服务器上。
如果我 运行 在本地运行应用程序,我可以通过邮递员(GET,POST)与 api 交互,并且一切都按预期的 good/bad 工作.
所以我构建了公开端口的映像,在发布端口的同时部署了 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 检查,所有容器都具有相同的网络设置,我什至 运行 总体上存在差异 docker 检查以找到解决方案的线索 - 那里一点头绪都没有。
- 如果我通过 docker exec -it 进入 docker 容器...并使用 curl 检查所有网络功能:一切正常。
- 另外两个容器(neo4j 和 mongodb)可以从外部访问 a.k.a。主机。
- 我自己的python应用容器没有。
因此我肯定遗漏了一些东西,但我无法弄清楚它是什么。 Docker文件:
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构建命令:
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 当我 运行 它针对 docker 化版本(端口 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>
到目前为止我尝试了什么(除了我在互联网上找到的所有东西):
- 使用其他 IP 调用 FLASK 运行,包括 0.0.0.0、localhost 和 与 docker 系统和各种其他端口兼容的 IP。
- 将不同的 docker 桥接网络分配给容器(默认和 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(未 docker 化)-> mongodb@docker :有效
- mypythonapplication@host(未 dockerized)-> neo4j@docker:有效
curl/postman@host -> mypythonapplication@host(未 dockerized):有效
如果我登录:docker exec mypythonapplication -it sh,然后使用 curl 或 ping 或任何我得到我期望的响应,所以:
- 我的python应用程序@docker -> mongodb@docker:有效
mypythonapplication@docker -> neo4j@docker :有效
curl@host -> mypythonapplication@docker:不起作用
- postman@host -> 我的pythonapplication@docker:不起作用
感谢您的任何提示!
您的问题很可能是由使用 "wrong" IP 的 flask 引起的:
Running on http://127.0.0.1:5000/
flask 的默认设置是仅在本地主机上侦听,在这种情况下,它将是本地主机 在 容器中,而不是 docker 主机的本地主机。
尝试像这样启动烧瓶:
flask.run(host='0.0.0.0', port=5000)