在 Heroku 代码 H10 路径"/"和"/favicon.ico"上提供带有独角兽的 Flask + React 应用程序



我试图使用 Gunicorn 使用 Flask API 提供一个原版 React 应用程序(使用 create-react-app 创建,没有进一步修改 - 只是创建了 react 应用程序并按原样构建(,但它在代码为 H10 的 Heroku 上失败了。我无法确定应用程序失败的原因。它在当地工作正常。不确定这是否是原因,我在本地使用了虚拟环境(venv(。知道为什么它会失败吗?谢谢!

Heroku 日志中的错误如下。

2020-06-13T03:20:19.425468+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=testdeployd.herokuapp.com request_id=302fe53f-2346-4c31-bf69-a6411da8a7b1 fwd="173.68.90.222" dyno= connect= service= status=503 bytes= protocol=https
2020-06-13T03:20:19.806856+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=testdeployd.herokuapp.com request_id=ea82a928-dcab-4931-a60b-8d63f4417c0a fwd="173.68.90.222" dyno= connect= service= status=503 bytes= protocol=https
2020-06-13T03:20:20.166173+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=testdeployd.herokuapp.com request_id=3c673c5f-ad5f-466d-92b0-830cdaff4f48 fwd="173.68.90.222" dyno= connect= service= status=503 bytes= protocol=https

目录结构如下。

myapp
|->api
|->api.py
|->.flasenv
|->venv
|->build
|->node_modules
|->public
|->src
...
|->Procfile
|->requirements.txt

api.py 的内容如下。

import flask
app = flask.Flask(__name__, static_folder="../build", static_url_path="/")

@app.route("/")
def index():
return app.send_static_file("index.html")

我把以下内容放在我的Procfile中。

web: gunicorn -b :5000 --pythonpath api api:app

添加了以下package.json文件。

"proxy": "http://localhost:5000"

下面是一个例子

目录结构:

├── api
│   ├── app.py
│   ├── __init__.py
├── build
│   ├── asset-manifest.json
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   ├── precache-manifest.8561e2012c98e084450b035cf3321061.js
│   ├── robots.txt
│   ├── service-worker.js
│   └── static
│       ├── css
│       ├── js
│       └── media
├── gunicorn.conf.py
├── Pipfile
├── Pipfile.lock
├── static
└── templates
#app.py
from flask import Flask, request
app = Flask(__name__, static_folder='../build', static_url_path="/")

@app.route('/')
def hello_world():
return app.send_static_file('index.html')

if __name__ == '__main__':
app.run()
#gunicorn.conf.py
# thanks https://github.com/tiangolo/meinheld-gunicorn-flask-docker/blob/master/python3.7/Dockerfile
import json
import multiprocessing
import os
workers_per_core_str = os.getenv("WORKERS_PER_CORE", "2")
web_concurrency_str = os.getenv("WEB_CONCURRENCY", None)
if os.getenv('FLASK_ENV', 'development') == 'production':
host = os.getenv("HOST", "0.0.0.0")
port = os.getenv("PORT", "8000")
else:
host = os.getenv("HOST", "0.0.0.0")
#  on a unix-like environment, ports < 1024 (like 80) will require superuser privileges.
# port need as same as config.config.py SERVER_NAME port
port = os.getenv("PORT", "5000")
bind_env = os.getenv("BIND", None)
use_loglevel = os.getenv("LOG_LEVEL", "info")
if bind_env:
use_bind = bind_env
else:
use_bind = f"{host}:{port}"
cores = multiprocessing.cpu_count()
workers_per_core = float(workers_per_core_str)
default_web_concurrency = workers_per_core * cores
if web_concurrency_str:
web_concurrency = int(web_concurrency_str)
assert web_concurrency > 0
else:
web_concurrency = int(default_web_concurrency)
# Gunicorn config variables
loglevel = use_loglevel
workers = web_concurrency
bind = use_bind
keepalive = 120
# For debugging and testing
log_data = {
"loglevel": loglevel,
"workers": workers,
"bind": bind,
# Additional, non-gunicorn variab`les
"workers_per_core": workers_per_core,
"host": host,
"port": port,
}
print(json.dumps(log_data))

gunicorn -c gunicorn.conf.py  api.app:app

您可以在 127.0.0.1:5000 中看到这一点 图像

注意

我使用创建-反应-应用程序创建项目,然后使用yarn build(我没有更改任何内容(

你可以只使用flask run && yarn start进行开发,并且可能需要flask-cors烧瓶核心来允许开发中的烧瓶核心

最新更新