python - Docker Container 中表单 POST 请求的烧瓶处理
问题描述
我正在尝试让一个在 Docker 容器中运行的小型 Web 应用程序在 Docker 方面的经验很少。webapp 使用来自表单的输入,呈现模板并将其作为文本文件返回给用户。
如果我在本地运行应用程序,一切都会按预期工作。如果我在 Docker 容器中运行应用程序,我可以访问每个静态站点。在表单中按“提交”时,我收到“连接被拒绝”错误。在 Flask 调试器中,我没有看到任何事情发生,这让我相信表单数据永远不会到达 Flask 或 Flask,无论出于何种原因(缺少模块?)未能在 Docker 中向我发送文件。
通过研究,我认为我不需要添加任何本地防火墙规则。我意识到 Docker 容器有点大,我可以使用 alpine 和 gunicorn 来代替 centos,但此时我并不是在寻找效率。
Docker 主机正在运行 CentOS 7。
要求.txt:
Flask==1.1.2
码头工人文件:
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 设置中的一个步骤,还是我可以做额外的调试?
解决方案
看起来是 Docker 配置的问题。我假设您使用的是 Docker for Windows 或替代方案,而不是 Docker Toolbox。
运行docker ps
并查看 PORTS 部分。docker 主机的 localhost 和 docker 容器的暴露端口之间应该有绑定。该部分应为0.0.0.0:5000->5000/tcp
.
你并不是说你是如何运行你的容器的。要实现端口绑定,您应该添加-p
参数。一个例子是docker run -p 5000:5000 image_name
我建议阅读基本的 Docker 文档。它不会太长,应该让您更清楚地了解它是如何工作的。
推荐阅读
- python - 如何在 Google Colab 的笔记本中显示图像(如在 Anacondan Jupyter Notebook 中)?
- python - 如何在 Discord.py 重写中赋予某人一个角色
- postgresql - 使用 docker-compose 运行 Sonarqube 和 postgresql 时,不遵守声纳仪表板上的用户名和密码
- android - 与水平 RecyclerView 上的选定项目一起滚动的 TextView
- javascript - 减少没有初始值的空数组
- java - 让我的代码高效循环 10 000 000 000 次的任何想法
- php - 检查用户是否在给定时间在php中工作
- node.js - SyntaxError:意外的令牌
- amazon-web-services - AWS RDS VPC 安全性
- c++ - 如何对同一数组索引下的结构成员进行排序?