在Docker容器中运行Flask应用程序

13

我已经构建了一个包含简单Flask测试应用程序的Docker镜像:

from flask import Flask 

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0')

使用 Dockerfile 文件:
FROM ubuntu:latest
RUN apt-get update -y
RUN apt-get install -y python-pip python-dev build-essential
COPY . /app
WORKDIR /app
RUN pip install -r /app/requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]

Docker 镜像是通过命令 docker build -t flask-app . 构建的,现已成功创建:
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
flask-app           latest              fab0d79fd7ac        8 minutes ago       642.2 MB
ubuntu              latest              104bec311bcd        5 weeks ago         129 MB

我已经使用以下方式运行它:

$ docker run -d -p 5000:5000 flask-app
e92b249dd02ca44489069b783fa9be713c7a14ea893061194e37c80f16d8c931

我假设可以通过将浏览器指向http://localhost:5000/来测试应用程序,但是我遇到了超时。可能出了什么问题?

5个回答

12

从这里看起来一切都很好。让我们进行一些调试。

首先,让我们通过指定一个名称来启动容器:

docker run -d -p 5000:5000 --name flask-app-test flask-app

您还可以避免使用 -d 标志,并将日志输出到屏幕上。

首先检查 Flask 应用程序是否真的在运行,或者它是否已崩溃。从简单的 docker ps 开始(查看是否有任何奇怪的内容),然后是 docker logs flask-app-test(这些是 Flask 应用程序的日志,它是否已崩溃?有没有什么奇怪的东西?)

如果一切看起来都很好,那么现在是时候进入容器了。尝试使用 docker exec -ti flask-app-test bash 进入容器。一旦进入,通过 apt-get install wget 安装 wget,然后通过执行 wget http://localhost:5000cat(跟随着 lscat file.html, 或者以其它名字命名)测试网站是否能够从内部正常工作。


docker logs flask-app-test shows * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger pin code: 236-035-556, but $ docker exec -ti bash flask-app-test shows Error response from daemon: No such container: bash - srm
@srm 抱歉,正确的 docker-exec 命令是 docker exec -ti flask-app-test bash。现在会编辑答案。 - Cristian Baldi
啊,好的,它返回了HTML响应:“Hello World!”,所以它在容器内运行正常。我理解容器没有GUI,所以没有办法使用浏览器测试应用程序? - srm
我们应该将端口5000映射到主机上,所以在本地浏览器中输入http://0.0.0.0:5000应该可以工作。但我不明白为什么它没有工作。 - Cristian Baldi
1
从容器外部,我尝试使用 curl http://0.0.0.0:5000/ 命令,但是返回了以下错误信息:curl: (7) Failed to connect to 0.0.0.0 port 5000: Connection refused - srm
@srm,我也遇到了同样的错误,你找到解决方案了吗?如果有的话,能否请你发布一下解决方案? - M005

3
  1. 获取容器id:

[sudo] docker ps -qf "name=<containername>"

  1. 获取该容器的ip地址:

docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container_id>

  1. 然后连接到 http://<the_resulting_ip>:5000/

1
正如我回复@cristian-baldi所说,我已经让它工作了。 - srm
谢谢您的回答,但是当我运行命令 sudo docker inspect -- format .... 时,我什么也没有得到。 - Catalina Chircu
@CatalinaChircu 如果你什么都没有得到,那应该意味着你的容器不再存在了,当你执行 docker ps -a 命令时,你能看到它吗? - lee-pai-long
@lee-pai-long:谢谢你的回答。实际上,我已经解决了我的问题,并且在运行docker ps时一切都很好。我的问题是我必须将CMD=["app.py"]更改为CMD ["flask", "run", "--host", "0.0.0.0"],并且没有任何ENTRYPOINT。我还在运行时添加了指令--interactive - Catalina Chircu
1
@CatalinaChircu 我很高兴你解决了问题。祝你一切顺利。 - lee-pai-long

2

我在我的系统上执行了以下步骤:

  1. 复制了您的flask代码和Dockerfile
  2. 创建了一个包含flask的requirements.txt文件,第一行是flask
  3. 像你一样构建并运行图像

它在我这里很好用:

$ curl localhost:5000
Hello World!

Docker进程运行正常,日志检查良好:

  $ docker ps
  CONTAINER ID        IMAGE               COMMAND             CREATED               STATUS              PORTS                    NAMES
  0c0228a88719        flask-app           "python app.py"     25 seconds ago      Up 24 seconds       0.0.0.0:5000->5000/tcp   frosty_borg

$ docker logs 0c0228a88719
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger pin code: 216-035-222
172.17.0.1 - - [22/Jan/2017 12:56:37] "GET / HTTP/1.1" 200 -

当您启动Docker容器时,请检查它是否正在监听端口5000。例如,在我的系统上:

     $ netstat -atn | grep 5000
     tcp6       0      0  ::1.5000               *.*                    LISTEN     
     tcp4       0      0  *.5000                 *.*                    LISTEN     
     $ docker stop 0c0228a88719
0c0228a88719
     $ netstat -atn | grep 5000
     $ # stops listening

重要的是,您如何运行Docker,它是在Linux桌面机上本地运行吗?还是在Mac / Windows主机上的Linux虚拟机中运行(通过像docker machine或其他方法的服务)?如果是这样,那么问题可能是您应该访问的IP不是localhost,而是虚拟机的IP地址。


我正在使用Mac,并且Docker容器通过Docker for Mac运行。正如我回复@cristian-baldi的那样,我已经让它工作了。 - srm

1
也许您的Docker引擎未在启动命令所在的同一操作系统上运行。例如,如果您在Windows上使用Docker,则Docker引擎通常在虚拟机内运行,并具有不同的IP地址,因此您需要编写http://[IP虚拟机]:5000/

在某些配置中,正确的URL是http://192.168.99.100:5000/(因为默认情况下,在某些配置中该虚拟机的IP地址为192.168.99.100)。

1
在Dockerfile中缺少这部分内容。
COPY ./requirements.txt /app/requirements.txt

Add this line to your Dockerfile before

app.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0')

requirements.txt

Flask==0.10.1
#or it can be any version

Dockerfile
FROM ubuntu:16.04
MAINTANER Your Name "youremail@domain.tld"
RUN apt-get update -y && \
    apt-get install -y python-pip python-dev
#your Dockerfile is missing this line
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt
COPY . /app
ENTRYPOINT [ "python" ]
CMD [ "app.py" ]

运行 Docker 命令

docker build -t flaskapp:latest .
#flask runs in default port 5000
docker run -d -p 5000:5000 flaskapp

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