Luca Faggianelli
Luca Faggianelli

Reputation: 2532

Google App Engine: Static file referenced by handler not found: ./dist/index.html

I have a project on Google Cloud Platform with Google App Engine which has 2 services, 1 NodeJS backend and a 1 for serving the static frontend.

My directory structure is like as following:

backend/
- app.yaml # service: api

front/
- app.yaml # service: default
- dist/
- src/
- - *.ts
- - *.vue

I deploy both the services, both build via Cloud Build and successfully deploy. The api is rightfully accessible at api.mydomain.com but when I visit the frontend at mydomain.com I get a 404 and in GCP log I found this: Static file referenced by handler not found: ./dist/index.html.

Now I'm hitting my head to the wall for 1 day but still can't figure out what's wrong, I checked the source code deployed on App Engine and the index.html file is there:

enter image description here

This is the content of app.yaml for the frontend and he's crafted for serving a VueJS SPA (PS: I also tried removing the leading ./ from path):

runtime: nodejs12

env_variables:
  NODE_ENV: 'production'

handlers:

# Serve all static files with url ending with a file extension
- url: /(.*\..+)$
  secure: always
  static_files: ./dist/\1
  upload: ./dist/.*\..+$

# Catch all handler to index.html
- url: /.*
  secure: always
  static_files: ./dist/index.html
  upload: ./dist/index.html

Do you know what's going on?

Upvotes: 0

Views: 429

Answers (2)

Luca Faggianelli
Luca Faggianelli

Reputation: 2532

At the end I solved creating a NodeJS static file server + rewrite rules for SPA apps, it's pretty basic and it uses koa and koa-static dependencies (koa-logger is optional):

const Koa = require('koa')
const koaLogger = require('koa-logger')
const koaStatic = require('koa-static')

const RE_ASSET_PATH = /\.\S{2,4}$/
const PORT = process.env.PORT || 3000

const app = new Koa()

app.use(koaLogger())

app.use(async (ctx, next) => {
  if (!ctx.url.match(RE_ASSET_PATH)) {
    ctx.url = '/'
  }

  await next()
})

app.use(koaStatic('dist'))

app.listen(PORT, () => {
  console.log('Client served at port', PORT)
})

the server runs via app.yaml, which is now ~empty:

runtime: nodejs12

finally I added a start script in package.json

"start": "node server.js",

Upvotes: 0

Alex
Alex

Reputation: 5286

in your app.yaml try changing ./dist/ to dist/ so:

handlers:

# Serve all static files with url ending with a file extension
- url: /(.*\..+)$
  secure: always
  static_files: dist/\1
  upload: dist/.*\..+$

# Catch all handler to index.html
- url: /.*
  secure: always
  static_files: dist/index.html
  upload: dist/index.html

Additionally see my answer to this question that is similar to yours. I think it's a bad idea to have your catch-all handler just return index.html (look at EDIT 1 & EDIT 2)

My react frontend is not changing when I deploy to Google App Engine

Upvotes: 1

Related Questions