如何使用代理将 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 提供文件很慢。对我来说,它目前运行良好,因为它是两者中“更容易”的一个,而且看起来你可以轻松地切换到这条路。

因此,我进行了以下更改:

  1. 我将目录结构更改为:
Top Level
-> directories after using create-react-app
application_folder
-> api
-> -> app.yaml 
-> -> main.py
  1. 我没有在 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")
  1. 我将以下行添加到 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 文件。 示例:

  1. 使用 npm run build

    构建您的 React 应用程序
  2. 将构建文件复制到名为 build 的新文件夹中的 Flask 应用程序。

  3. 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 等服务来打包应用程序并将它们部署到应用程序引擎上。