【问题标题】:Flask handling of form POST request in Docker ContainerDocker Container 中表单 POST 请求的烧瓶处理
【发布时间】:2020-10-07 08:47:58
【问题描述】:

我正在尝试让一个在 Docker 容器中运行的小型 web 应用程序,但对 Docker 的经验很少。 webapp 使用来自表单的输入,呈现模板并将其作为文本文件返回给用户。

如果我在本地运行应用程序,一切都会按预期运行。 如果我在 Docker 容器中运行应用程序,我可以访问每个静态站点。在表单中按“提交”时,我收到“连接被拒绝”错误。 在 Flask 调试器中,我没有看到任何发生的事情,这让我相信表单数据永远不会进入 Flask 或 Flask 出于任何原因(缺少模块?)无法在 Docker 中向我发送文件。

通过研究,我认为我不需要添加任何本地防火墙规则。我意识到 Docker 容器有点大,我可以使用 alpine 和 gunicorn 来代替 centos,但此时我并不追求效率。

Docker 主机正在运行 CentOS 7。

Requirements.txt:

Flask==1.1.2

Docker 文件:

FROM centos:centos7

COPY ./requirements.txt /app/requirements.txt
RUN yum install -y python3 python3-pip python3-devel

WORKDIR /app
RUN pip3 install --no-cache-dir -r requirements.txt
COPY . /app

ENTRYPOINT ["python3"]
CMD ["flaskapp.py" ]

Docker 启动命令

docker run -d -p 5000:5000 flaskapp

在本地运行python3 flaskapp.py并提交表单时的输出

PS c:\user> python3.exe .\flaskapp.py
 * Serving Flask app "flaskapp" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 205-510-917
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [17/Jun/2020 15:31:28] "[37mGET /generator HTTP/1.1[0m" 200 -
127.0.0.1 - - [17/Jun/2020 15:32:00] "[37mPOST /result HTTP/1.1[0m" 200 -

Docker 容器中的相同操作

]# docker run -p 5000:5000 flaskapp
 * Serving Flask app "flaskapp" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 161-592-324
10.10.10.10 - - [17/Jun/2020 13:30:10] "GET /generator HTTP/1.1" 200 -

html 中的表单操作

<form action = "http://localhost:5000/result" method = "POST">
    <p><input type = "submit" value = "submit" /></p>

Flaskapp.py 缩短为仅包含我的 send_file 用法

from flask import Flask, render_template, request, send_file
import ipaddress
import zipfile
from pathlib import Path

app = Flask(__name__)

[...]

# generate configuration when data is received from generator form
@app.route('/result', methods=['POST', 'GET'])
def result():
    [...] some code, input checks, text manipulation

        # check folder content for .cfg files and add them to a zip archive
        with zipfile.ZipFile(temp_zipfile, mode='w') as z:
            for file in base_path.iterdir():
                if file.suffix == ".cfg":
                    try:
                        z.write(file, file, zipfile.ZIP_DEFLATED)
                    except:
                        continue
        # send the zip file to the user
        return send_file(temp_zipfile, as_attachment=True, mimetype='application/zip',attachment_filename="configurations.zip")
    # if HA is not used, send a cfg file directly
    elif result["cluster"] == "no":
        configfile = config_filepath + result["HOSTNAME"] + ".cfg"
        with open(configfile, "w+") as cfg:
            cfg.write(content)
        return send_file(configfile, as_attachment=True,attachment_filename='configurations.cfg')

我是在 Docker 设置中遗漏了一个步骤,还是我可以进行额外的调试?

【问题讨论】:

  • 您的直觉似乎是正确的——“连接被拒绝”表示服务器可用但端口 5000 未打开。使用浏览器的开发人员工具仔细检查您是否向正确的地址发出请求。

标签: python docker flask


【解决方案1】:

看来是 Docker 配置有问题。我假设您使用的是 Docker for Windows 或替代方案,而不是 Docker Toolbox。

运行 docker ps 并查看 PORTS 部分。 docker 主机的 localhost 和 docker 容器的暴露端口之间应该有绑定。该部分应为0.0.0.0:5000-&gt;5000/tcp

您并不是在说您是如何运行您的容器的。要实现端口绑定,您应该添加-p 参数。一个例子是docker run -p 5000:5000 image_name

我建议阅读基本的 Docker 文档。它不会太长,应该让您更清楚地了解它是如何工作的。

【讨论】:

  • 感谢您的回复,我已经在帖子中添加了平台(CentOS 7)和docker run命令。绑定是通过 -p 5000:5000 实现的,当我获得 /generator 页面时,绑定通常可以正常工作。明天我再看一下 Docker 文档,谢谢你的建议。
【解决方案2】:

Kendas 的评论指出了明显的问题,表单操作指向无法工作的 localhost。将表单操作更改为服务器的 IP 地址,现在一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-24
    • 2014-07-23
    • 2020-06-22
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多