如何使用代理将 Flask API 和 React 前端微服务部署到 Google App Engine?
How Do I Deploy Flask API & React Frontend Microservices to Google App Engine with Proxy?
我花了相当多的时间阅读 Stack Overflow 问题,但找不到我要找的东西。
我正在创建一个要部署在 GAE 上的 Flask API 和 React 前端。我的目录结构如下所示:
application_folder
-> api
-> -> app.yaml
-> -> main.py
-> react_frontend
-> -> app.yaml
-> -> {directories after using create-react-app}
用于开发
1.) React应用的package.json
,我设置了一个代理:
"proxy": "http://localhost:5000/"
我的 React 前端 运行ning 在端口 3000 上。
2.) 我在 React 前端的 App.js
文件中这样获取:
fetch('api/endpoint')
如梦如幻。
生产用
但是,在部署到 GAE 时,我必须进行以下更改:
1.) 从 package.json
中删除代理。当我在生产环境中的 React 前端收到 404 错误时,我找不到使用代理的方法。
2.) 在 main.py
.
中将 Access-Control-Allow-Origin 添加到 Flask API
@app.route("/api/endpoint", methods=["GET"])
def endpoint():
resp = make_response({"cat": 15})
resp.headers["Access-Control-Allow-Origin"] = "*"
return resp
3.) 现在,我必须从 App.js
.
获取绝对路径
fetch('flask-production-domain.com/api/endpoint')
我的问题是,您能否推荐一种部署到 production/setting 本地开发的方法,这样我在部署到生产环境时就不必重写代码库?
顺便说一下,我的 app.yaml 文件是这样读的:
# api app.yaml
runtime: python38
env_variables:
none_of: "your_business"
# frontend app.yaml
runtime: nodejs12
service: banana
handlers:
- url: /static
static_dir: build/static
- url: /(.*\.(json|ico|js))$
static_files: build/
upload: build/.*\.(json|ico|js)$
- url: .*
static_files: build/index.html
upload: build/index.html
提前致谢。
编辑
我接受了迪尚特的回答,但我与他们建议的略有不同。
首先,这两个资源太棒了。这个人在 Flask 上写了“书”:
在第二个视频中,他描述了两种部署方法。第一个类似于 dishant 建议的。在视频中,Miguel 将此选项描述为他描述的两个选项中他不太喜欢的选项,因为从 python 提供文件很慢。对我来说,它目前运行良好,因为它是两者中“更容易”的一个,而且看起来你可以轻松地切换到这条路。
因此,我进行了以下更改:
- 我将目录结构更改为:
Top Level
-> directories after using create-react-app
application_folder
-> api
-> -> app.yaml
-> -> main.py
- 我没有在
app.yaml
文件中创建路由,而是将以下内容添加到 main.py
fie:
app = Flask(__name__, static_folder="build", static_url_path="/")
@app.route("/")
def index():
return app.send_static_file("index.html")
- 我将以下行添加到 package.json 以创建一个脚本来构建静态文件并将其移动到 api 目录。
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"create-app": "yarn build && rm -r api/build && cp -r build api/build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
所以现在我运行yarn create-app
来建造。
我会调查 Travis 的 CI/CD,因为我以前用过它。
如果您想在部署中使用代理,您确实没有太多选择。例如,在大多数情况下,您需要将代理与 App Engine 一起使用,需要在 Compute Engine 上使用一个实例,因此您可以设置静态 IP 并对其进行更好的配置 - 如本例所述 .
另一种选择是使用 Extensible Service Proxy (ESP to an App Engine Flex environment, using Cloud Endpoints. As explained here 部署您的 API 的后端代码,您可以这样配置,这样 ESP 就可以获得您的 API 的 Endpoints 配置,这允许 ESP 代理请求和响应,以便 Endpoints 可以管理您的 API.
这些是一些不同的方法,可能会让您了解如何做,更多的是作为起点而不是解决方案。但是,您在这里的选择有点受限,因为您的用例是特定的,并且 GAE 也有一些特定的设置可用。我会建议您继续做现在有效的事情,然后尝试使用其他选项之一。
来自https://create-react-app.dev/docs/proxying-api-requests-in-development/:
Keep in mind that proxy only has effect in development (with npm
start), and it is up to you to ensure that URLs like /api/todos point
to the right thing in production. You don’t have to use the /api
prefix. Any unrecognized request without a text/html accept header
will be redirected to the specified proxy.
您不会在已部署环境(应用引擎)中从内存中为您的前端提供服务。相反,您应该构建您的应用程序并将其与 Flask 应用程序一起打包,并在 app.yaml 中设置路由以正确指向前端和后端。
您只需要 1 个 app.yaml 文件。
示例:
使用 npm run build
构建您的 React 应用程序
将构建文件复制到名为 build 的新文件夹中的 Flask 应用程序。
app.yaml:
runtime: python38
env_variables:
none_of: "your_business"
handlers:
# frontend
- url: /static
static_dir: build/static
- url: /(.*\.(json|ico|js|html))$
static_files: build/
upload: build/.*\.(json|ico|js|html)$
# backend
- url: /.*
script: auto
您可以利用 ci/cd 云构建或 Jenkins 等服务来打包应用程序并将它们部署到应用程序引擎上。
我花了相当多的时间阅读 Stack Overflow 问题,但找不到我要找的东西。
我正在创建一个要部署在 GAE 上的 Flask API 和 React 前端。我的目录结构如下所示:
application_folder
-> api
-> -> app.yaml
-> -> main.py
-> react_frontend
-> -> app.yaml
-> -> {directories after using create-react-app}
用于开发
1.) React应用的package.json
,我设置了一个代理:
"proxy": "http://localhost:5000/"
我的 React 前端 运行ning 在端口 3000 上。
2.) 我在 React 前端的 App.js
文件中这样获取:
fetch('api/endpoint')
如梦如幻。
生产用
但是,在部署到 GAE 时,我必须进行以下更改:
1.) 从 package.json
中删除代理。当我在生产环境中的 React 前端收到 404 错误时,我找不到使用代理的方法。
2.) 在 main.py
.
@app.route("/api/endpoint", methods=["GET"])
def endpoint():
resp = make_response({"cat": 15})
resp.headers["Access-Control-Allow-Origin"] = "*"
return resp
3.) 现在,我必须从 App.js
.
fetch('flask-production-domain.com/api/endpoint')
我的问题是,您能否推荐一种部署到 production/setting 本地开发的方法,这样我在部署到生产环境时就不必重写代码库?
顺便说一下,我的 app.yaml 文件是这样读的:
# api app.yaml
runtime: python38
env_variables:
none_of: "your_business"
# frontend app.yaml
runtime: nodejs12
service: banana
handlers:
- url: /static
static_dir: build/static
- url: /(.*\.(json|ico|js))$
static_files: build/
upload: build/.*\.(json|ico|js)$
- url: .*
static_files: build/index.html
upload: build/index.html
提前致谢。
编辑
我接受了迪尚特的回答,但我与他们建议的略有不同。
首先,这两个资源太棒了。这个人在 Flask 上写了“书”:
在第二个视频中,他描述了两种部署方法。第一个类似于 dishant 建议的。在视频中,Miguel 将此选项描述为他描述的两个选项中他不太喜欢的选项,因为从 python 提供文件很慢。对我来说,它目前运行良好,因为它是两者中“更容易”的一个,而且看起来你可以轻松地切换到这条路。
因此,我进行了以下更改:
- 我将目录结构更改为:
Top Level
-> directories after using create-react-app
application_folder
-> api
-> -> app.yaml
-> -> main.py
- 我没有在
app.yaml
文件中创建路由,而是将以下内容添加到main.py
fie:
app = Flask(__name__, static_folder="build", static_url_path="/")
@app.route("/")
def index():
return app.send_static_file("index.html")
- 我将以下行添加到 package.json 以创建一个脚本来构建静态文件并将其移动到 api 目录。
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"create-app": "yarn build && rm -r api/build && cp -r build api/build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
所以现在我运行yarn create-app
来建造。
我会调查 Travis 的 CI/CD,因为我以前用过它。
如果您想在部署中使用代理,您确实没有太多选择。例如,在大多数情况下,您需要将代理与 App Engine 一起使用,需要在 Compute Engine 上使用一个实例,因此您可以设置静态 IP 并对其进行更好的配置 - 如本例所述
另一种选择是使用 Extensible Service Proxy (ESP to an App Engine Flex environment, using Cloud Endpoints. As explained here 部署您的 API 的后端代码,您可以这样配置,这样 ESP 就可以获得您的 API 的 Endpoints 配置,这允许 ESP 代理请求和响应,以便 Endpoints 可以管理您的 API.
这些是一些不同的方法,可能会让您了解如何做,更多的是作为起点而不是解决方案。但是,您在这里的选择有点受限,因为您的用例是特定的,并且 GAE 也有一些特定的设置可用。我会建议您继续做现在有效的事情,然后尝试使用其他选项之一。
来自https://create-react-app.dev/docs/proxying-api-requests-in-development/:
Keep in mind that proxy only has effect in development (with npm start), and it is up to you to ensure that URLs like /api/todos point to the right thing in production. You don’t have to use the /api prefix. Any unrecognized request without a text/html accept header will be redirected to the specified proxy.
您不会在已部署环境(应用引擎)中从内存中为您的前端提供服务。相反,您应该构建您的应用程序并将其与 Flask 应用程序一起打包,并在 app.yaml 中设置路由以正确指向前端和后端。
您只需要 1 个 app.yaml 文件。 示例:
使用
构建您的 React 应用程序npm run build
将构建文件复制到名为 build 的新文件夹中的 Flask 应用程序。
app.yaml:
runtime: python38 env_variables: none_of: "your_business" handlers: # frontend - url: /static static_dir: build/static - url: /(.*\.(json|ico|js|html))$ static_files: build/ upload: build/.*\.(json|ico|js|html)$ # backend - url: /.* script: auto
您可以利用 ci/cd 云构建或 Jenkins 等服务来打包应用程序并将它们部署到应用程序引擎上。