我想在本地运行dockerized flask服务器并访问我在其中定义的所有路由。设置重现我的问题:
app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
Dockerfile
from python:3.7-alpine
COPY app.py app.py
RUN pip install flask
CMD [ "flask", "run" ]
构建此容器可以正常工作。在the documentation和some in-depth examples之后,用docker run -p 5000:5000 flask
运行它应该可以解决问题。它启动了容器,看起来不错:
* 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)
docker ps
告诉我端口映射似乎也起作用:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0581bf3af0ea flask "flask run" 25 seconds ago Up 24 seconds 0.0.0.0:5000->5000/tcp nervous_brown
但是当我尝试在浏览器中访问该网站时,我只会收到404。
有趣的是,使用docker run --net=host flask
运行图像确实可以,但是我宁愿不使用它。
我真的很不了解网络的工作方式,我在做什么错了?
答案 0 :(得分:3)
将运行flask
的主机更改为'0.0.0.0'
。容器中的本地主机仅位于容器本地,而不是计算机本地:
flask run -h 0.0.0.0
这会将应用程序绑定到容器上的所有网络接口,并且您的计算机可以访问
Docker容器是它们自己的小独立网络。它们具有外部接口eth0
,具有外部ip地址,具有路由表和本地主机。 Localhost不会映射到外部接口,尝试这样做通常是一种不好的做法。
我们以一个简单的容器为例,我将像这样运行一个Linux容器:
docker run -it ubuntu bash
现在,我可以通过运行apt-get update && apt-get install net-tools
来检查该容器内的网络详细信息:
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 11286 bytes 16471897 (16.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3421 bytes 189224 (189.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo
是回送或本地主机。它是一个完全独立的接口,而不是面向外部的eth0
。您可以绑定到它,但我不能保证IP地址一直都是相同的。因此,最简单的方法是将烧瓶绑定到它们的 all 。
环回仅是网络与自身进行通信,仅此而已。它不需要具有面向外部的组件,因为从设计上来说,它不打算用于外部通信