Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google App Engine - keep previous version's static files

We've deployed a Vue SPA to Google App Engine and it's served completely by the static handlers.

The issue that we are facing is that if a user is active on our site mid-deploy, then their old Webpack chunk manifest becomes invalid (since some chunks' hashes are overwritten). If they now try to route to a new page and that page tries to fetch a chunk that got overwritten, we get the following error:

ChunkLoadError: Loading chunk Conversations failed.
(error: https://example.com/js/Conversations.71762189.js)

Ideally, we'd like to keep N (2-3?) previous versions of the app's static files.

Is our only option to push all the assets to a Cloud Storage Bucket? If so, how would we go about pruning older versions?

Here is my app.yaml for reference:

runtime: nodejs10
instance_class: F4
automatic_scaling:
  min_instances: 2
  max_instances: 10
default_expiration: "30d"
error_handlers:
  - file: default_error.html
handlers:
- url: /api/*
  secure: always
  redirect_http_response_code: 301
  script: auto
- url: /js/*
  secure: always
  redirect_http_response_code: 301
  static_dir: dist/js
- url: /css/*
  secure: always
  redirect_http_response_code: 301
  static_dir: dist/css
- url: /img/*
  secure: always
  redirect_http_response_code: 301
  static_dir: dist/img
- url: /(.*\.(json|js|txt))$
  secure: always
  redirect_http_response_code: 301
  static_files: dist/\1
  upload: dist/.*\.(json|js|txt)$
  expiration: "10m"
- url: /.*
  secure: always
  redirect_http_response_code: 301
  static_files: dist/index.html
  upload: dist/index.html
  expiration: "2m"
like image 881
kano Avatar asked Mar 04 '23 08:03

kano


1 Answers

The issue typically happens when the deployment overwrites an existing service version which receives traffic (i.e. the service version is not changed). From Deploying an app:

Note: If you deploy a version that specifies the same version ID as a version that already exists on App Engine, the files that you deploy will overwrite the existing version. This can be problematic if the version is serving traffic because traffic to your application might be disrupted. You can avoid disrupting traffic if you deploy your new version with a different version ID and then move traffic to that version.

As long as a service version is deployed and not deleted or overwritten its respective static assets remain accessible.

To prevent the issue always deploy using a fresh service version, then (gradually) migrate traffic to the newly deployed version. Keeping the latest N service versions around will give you those N sets of static assets you desire.

In general, this deployment practice is good/recommended for a few other reasons:

  • avoids potential outages, see Continuous integration/deployment/delivery on Google App Engine, too risky?
  • avoids potential traffic loss while GAE spins up enough new version instances to handle the traffic load, see 2nd half of GAE shutdown or restart all the active instances of a service/app

Potentially of interest: Google Frontend Retention between deployments

like image 64
Dan Cornilescu Avatar answered Mar 10 '23 22:03

Dan Cornilescu