Flask + Docker =>无连接[重复]

c9qzyr3d  于 12个月前  发布在  Docker
关注(0)|答案(2)|浏览(132)

此问题在此处已有答案

Deploying a minimal flask app in docker - server connection issues(8个答案)
6天前关闭
我在Flask中实现了一个基本的REST API。我想尝试使用Docker将其容器化。我对Docker完全陌生,但根据我在各种论坛上的了解,这是我设置的。
Dockerfile

FROM python:3.11
WORKDIR     /app
COPY ./requirements.txt /app/requirements.txt
COPY .env /app/.env
COPY . /app
RUN python3 -m pip install -r /app/requirements.txt

EXPOSE 5000
ENTRYPOINT ["python3"]
CMD ["app.py", "--host=0.0.0.0"]

字符串
requirements.txt

aiohttp==3.8.6
aiohttp-retry==2.8.3
aiosignal==1.3.1
async-timeout==4.0.3
attrs==23.1.0
blinker==1.6.3
certifi==2023.7.22
charset-normalizer==3.3.1
click==8.1.7
distlib==0.3.7
filelock==3.12.4
Flask==2.3.0
Flask-Cors==4.0.0
flask-marshmallow==0.14.0
Flask-MySQL==1.5.2
Flask-MySQLdb==2.0.0
Flask-SQLAlchemy==3.1.1
frozenlist==1.4.0
idna==3.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
marshmallow-sqlalchemy==0.29.0
multidict==6.0.4
mysqlclient==2.2.0
packaging==23.2
platformdirs==3.11.0
PyJWT==2.8.0
PyMySQL==1.1.0
python-dotenv==1.0.0
requests==2.31.0
six==1.16.0
SQLAlchemy==2.0.22
twilio==8.10.0
typing_extensions==4.8.0
urllib3==2.0.7
virtualenv==20.24.5
Werkzeug==3.0.0
yarl==1.9.2


app.py

from flask import Flask, request, jsonify, json
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.event import listens_for
from flaskext.mysql import MySQL
from flask_cors import CORS
from dataclasses import dataclass
from sqlalchemy import text
from urllib.parse import quote

app = Flask(__name__)
CORS(app, origins=["http://localhost:3000", "http://localhost:3000"])

db = SQLAlchemy()

mysql =MySQL()

@dataclass
class User(db.Model):

    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(46), nullable=False)#1
    lastname = db.Column(db.String(46), nullable=False)#1
    

    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

    def as_dict(self):
        excluded_fields = ['id']
        return {field.name:getattr(self, field.name) for field in self.__table__.c if field.name not in excluded_fields}

@dataclass
class User(db.Model):

    __tablename__ = 'user'
    __table_args__ = {'extend_existing': True} 

    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(46), nullable=False)#1
    lastname = db.Column(db.String(46), nullable=False)#1

    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

    def as_dict(self):
        excluded_fields = ['id']
        return {field.name:getattr(self, field.name) for field in self.__table__.c if field.name not in excluded_fields}


app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:[email protected]/test'

db.init_app(app)
with app.app_context():
    db.create_all()

@app.route('/users', methods=['GET'])
def get_user():
    users = User.query.all()
    return jsonify(users)

@app.route('/user/<firstname>', methods=['GET'])
def user_byfirstname(firstname):
    user = User.query.filter_by(firstname = firstname).first()
    return jsonify(user.as_dict())

if __name__ == '__main__':
   app.run(debug=True)


应用程序树:


的数据
然后我去终端,运行$ docker build -t myapp:latest
构建成功,我可以在Docker Desktop应用中看到我的应用
然后我就跑

$ docker run --rm -it -p 8080:5000 myapp:latest
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
/usr/local/lib/python3.11/site-packages/flask_sqlalchemy/model.py:144: SAWarning: This declarative base already contains a class with the same class name and module name as __main__.User, and will be replaced in the string-lookup table.
  super().__init__(name, bases, d, **kwargs)
 * Debugger is active!
 * Debugger PIN: 581-248-767


Docker Desktop显示myapp正在使用中。
到目前为止,一切顺利。但这就是我开始遇到问题的地方。
从主机(通过Postman),我无法访问端口8080上的应用程序:

127.0.0.1:8080/users


Postman抛出错误:Error: read ECONNRESET
我真的不知道该做什么或从这里去哪里,我尝试过的每一个来源都给了我一个轻微的变化,我已经尝试过了,我没有更接近让这个工作。请帮助,谢谢。

vybvopom

vybvopom1#

Flask服务器的输出指出它只在容器本地网络(127.0.0.1)上运行,而不是在所有接口上运行。
这是因为你正在使用python3 app.py --host=0.0.0.0运行flask开发服务器。当你这样运行它时,Flask使用默认值和通过函数app.run()给定的值运行。
推荐的方法是使用flask命令来运行你的应用,这样你就可以在外部配置flask,而不是硬编码变量,或者用你需要的变量修改你的app.run()

  • 推荐的方法是修改你的dockerfile并像这样使用flask:
FROM python:3.11-alpine
# Virtual envs not needed inside container
WORKDIR /app
COPY ./requirements.txt /app/requirements.txt
COPY . /app
RUN python3 -m pip install -r /app/requirements.txt

EXPOSE 5000
CMD ["flask", "--app=app", "run", "--host=0.0.0.0"]

字符串

  • 另一个选项是修改app.run()并添加host参数:
if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0")

fjnneemd

fjnneemd2#

使用gunicorn或其他生产级WSGI服务器启动flask应用程序。https://flask.palletsprojects.com/en/3.0.x/deploying/gunicorn/
https://flask.palletsprojects.com/en/3.0.x/deploying/
命令应该类似于:/path/to/python/install/or/venv/python -m gunicorn -b:5000 --access-logfile -error-logfile - wsgi:app

相关问题