Google App Engine - Razzle isomorphic react app - serve issues with no client bundles or assets

833 Views Asked by At

I haven't been able to take the default bare-skin razzle-app (https://github.com/jaredpalmer/razzle) and make it work when I deploy it to Google App Engine. If anyone has experience deploying isomorphic react apps to GAE, then any inputs would be great.

After deployment, it serves the html from the server.js (it only serves the html text for the route but nothing else - no application nor any assets on the page). As a proof of concept, I was returning different html content for different routes, and it apparently works as the html text content as well as head tags were different. However, there are no static assets on the site (no images, css or js).

Build process output:

razzle build

Creating an optimized production build...
Compiling client...
Compiled client successfully.
Compiling server...
Compiled server successfully.
Compiled successfully.

File sizes after gzip:

  48.22 KB  build/static/js/bundle.c798792d.js
  333 B     build/static/css/bundle.659481d8.css

the build directory contains:

> build
      > public 
            > static
                   > css
                   > js
                   > media
            > favicon and robots
     > static
            > media (same one as public/staic)
     > assets.json
     > server.js

Notice that the build/static/js doesn't exist. It's inside build/public/static/js. Is it weird? On accessing the site (only html text from the server), I checked the head if the client bundle waas sent or not. Itis fetching from a wrong location.

<script src="http://localhost:8081/static/js/bundle.js" defer="" crossorigin=""></script>

My package.json looks like :

{
  "name": "my-razzle-app",
  "version": "0.1.0",
  "license": "MIT",
  "scripts": {
    "start": "razzle start",
    "build": "razzle build",
    "test": "razzle test --env=jsdom",
    "start:prod": "NODE_ENV=production node build/server.js"
  },
  "dependencies": {standard
    "express": "^4.17.1",
    "razzle": "^3.0.0",
    "react": "^16.11.0",
    "react-dom": "^16.11.0",
    "react-router-dom": "^5.1.2"
  }
}

Note that GAE runs npm run start.

I'm currently using flex , standard never worked for me at all. app.yaml looks like:

env: flex
runtime: nodejs
service: web

Running locally :

razzle start

 WAIT  Compiling...


✔ Client
  Compiled successfully in 2.14s

✔ Server
  Compiled successfully in 153.86ms

ℹ 「wds」: Project is running at http://localhost:3001/
ℹ 「wds」: webpack output is served from undefined
ℹ 「wds」: Content not from webpack is served from /home/anz/Cogi/timecloud-client/my-app
ℹ 「wds」: 404s will fallback to /index.html
✅  Server-side HMR Enabled!
 started

I can access it at localhost:3000, not localhost:3001.

1

There are 1 best solutions below

3
On

Use a custom runtime to deploy your Razzle app on App Engine flexible environment. They key to the issue with deployments on App Engine with razzle apps relies on the fact that the process.env.PORT build-time variable's default is set to 3000 and in order to use App Engine you need to make your application's configuration to listen to port 8080 as stated on the documentation.

The process of deployment would consist of creating a Dockerfile, making sure your that the index.js of you razzle app listens to port 8080, building the docker image, pushing the image to Container Registry, creating an app.yaml for the custom runtime, and finally deploying the application to App Engine.

Assuming that your Google Cloud Platform project is ready to deploy applications on App Engine for the sake of simplicity you could use this existing Dockerfile to deploy a simple razzle app, by following this steps:

  1. On your Google Cloud Platform console open the Cloud Shell, set your project config with gcloud config set project YOUR-PROJECT-NAME and run export PROJECT_ID=YOUR-PROJECT-NAME to set the PROJECT_ID enviroment variable to your Project ID.
  2. git clone https://github.com/Sach97/razzle-k8s.git
  3. cd razzle-k8s/web/src
  4. Modify the index.js file in order to make sure the server listens to port 8080. Change this part of the code const port = process.env.PORT || 3000; to const port = 8080 or just hard code the 8080 value:
export default express()
  .use((req, res) => app.handle(req, res))
  .listen(8080, function(err) {
    if (err) {
      console.error(err);
      return;
    }
    console.log(`> Started on port ${port}`);
  });

  1. Go back to the razzle-k8s/web folder and build the image with docker build docker build -t gcr.io/${PROJECT_ID}/razzle:v1 . (the . at the end of the command is included).
  2. Push the image to Container Registry docker push gcr.io/${PROJECT_ID}/razzle:v1
  3. Create a deploy folder on the razzle-k8s directory mkdir deploy
  4. Go to the deploy folder cd deploy and create an app.yaml with the following configuration.
runtime: custom
env: flex
service: razzle
  1. Run gcloud app deploy --image-url gcr.io/${PROJECT_ID}/razzle:v1 to deploy your application with a custom runtime and type (Y) for yes to deploy your app using your razzle image.
  2. To view your application simply type gcloud app browse -s razzle and go to the URL. It should be of the form https://razzle-dot-your-project-name.appspot.com.