App Engine app.yaml handlers for built React app
Asked Answered
F

3

12

I'm trying to deploy production build of React app (created using create-react-app) to gcloud app engine flexible enviroment.

After running npm run build, the build folder has been created:

App directory tree

This is my app.yaml:

# [START runtime]
runtime: nodejs
env: flex
# [END runtime]

# [START handlers]
handlers:
  - url: /
    static_files: build/index.html
    upload: build/index.html
  - url: /
    static_dir: build
  # [END handlers]

When deployed to App Engine, the version configuration shows:

runtime: nodejs
api_version: '1.0'
env: flexible
threadsafe: true
handlers:
  - url: /
    application_readable: false
    static_files: build/index.html
    require_matching_file: false
    upload: build/index.html
  - url: '/(.*)'
    application_readable: false
    static_files: "build/\\1"
    require_matching_file: false
    upload: 'build/.*'
automatic_scaling:
  min_num_instances: 2
  max_num_instances: 20
  cpu_utilization:
    target_utilization: 0.5

The development app is being served instead of the production version from the build folder. What am I doing wrong?

Faa answered 5/12, 2018 at 13:22 Comment(0)
S
4

When deploying a GAE app/service the directory containing the app/service's app.yaml file being deployed is considered the app/service's top level directory and the content of that directory is what's being deployed. Which, in your case, matches what I suspect you're calling the development version.

If you want your build directory to be your app/service's top dir then you need to:

  • create an app.yaml file in the build dir (manually or instruct your build process to do it)

    Note: you need to adjust the paths in that file, since there won't be a build directory in the app's directory anymore. Or try to create inside it a build -> . symlink to itself, possibly allowing the use of the existing app.yaml content as-is, without adjusting the paths (not 100% certain this will work, though).

  • deploy that build/app.yaml file, not the one from the top (bsn) dir.

Straggle answered 5/12, 2018 at 22:14 Comment(2)
In order to deploy, the folder you deploy must have a app.yaml file in it, and if you run gcloud app delpoy while in the build folder, you'll get an error since there's no package.json file there. gcloud app deploy runs npm start by default or it looks for a server.js file. Which is why deploying from the project folder runs the app in dev mode. Are you suggesting deploying the whole repo still or are you suggesting deploying the build folder only, if so there's a missing step there on setting up a server.js file and a package.config. Have you been able to replicate your instructions?Pappose
@DmitriLarionov You may be right, I only looked at the app.yaml implications (I'm a python runtime user, not very familiar with the additional node.js specifics).Straggle
F
14

Modify the scripts in package.json to have GAE use serve to serve the build dir instead of the root directory.

Upon deployment, GAE will run npm start to begin serving your application. By changing what the start script maps to, you can have the build directory served as desired. You will have to use npm run local when doing local development with this setup, as you are changing what npm start is doing.

This process requires you to run npm run build before deploying to GAE. This will serve the build directory for you, but it does not automatically run the build process for you, so that must still be done to serve your latest code in /src.

Source: https://github.com/facebook/create-react-app/issues/2077

Code:

"scripts": {
  "start": "serve -s build",
  "prestart": "npm install -g serve",
  "local": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test --env=jsdom",
  "eject": "react-scripts eject"
}
Fritts answered 20/3, 2019 at 18:3 Comment(0)
T
8

GAE will run npm start to run your react app. Therefore you need to configure your package.json to tell GAE serve your build folder:

  "scripts": {
    "start": "serve -s build",
    ...
  },

Also need to configure your .yaml file accordingly:

handlers:
  - url: /
    static_files: build/index.html
    upload: build/index.html
  - url: /(.*)$
    static_files: build/\1
    upload: build/(.*)
Thanatopsis answered 17/11, 2019 at 4:21 Comment(0)
S
4

When deploying a GAE app/service the directory containing the app/service's app.yaml file being deployed is considered the app/service's top level directory and the content of that directory is what's being deployed. Which, in your case, matches what I suspect you're calling the development version.

If you want your build directory to be your app/service's top dir then you need to:

  • create an app.yaml file in the build dir (manually or instruct your build process to do it)

    Note: you need to adjust the paths in that file, since there won't be a build directory in the app's directory anymore. Or try to create inside it a build -> . symlink to itself, possibly allowing the use of the existing app.yaml content as-is, without adjusting the paths (not 100% certain this will work, though).

  • deploy that build/app.yaml file, not the one from the top (bsn) dir.

Straggle answered 5/12, 2018 at 22:14 Comment(2)
In order to deploy, the folder you deploy must have a app.yaml file in it, and if you run gcloud app delpoy while in the build folder, you'll get an error since there's no package.json file there. gcloud app deploy runs npm start by default or it looks for a server.js file. Which is why deploying from the project folder runs the app in dev mode. Are you suggesting deploying the whole repo still or are you suggesting deploying the build folder only, if so there's a missing step there on setting up a server.js file and a package.config. Have you been able to replicate your instructions?Pappose
@DmitriLarionov You may be right, I only looked at the app.yaml implications (I'm a python runtime user, not very familiar with the additional node.js specifics).Straggle

© 2022 - 2024 — McMap. All rights reserved.