Skip to main content

Deployment

Ceres is a bunch of static files (HTML, JS, CSS, JSON, images). After building, they get uploaded to Azure Blob Storage and served through the lstatic CDN.

Where Ceres lives

The built files are hosted at:

https://lstatic.refrens.com/ceres/

This is a CDN endpoint that serves static files from Azure Blob Storage. Here is the full path:

Azure Blob Storage ($web/ceres/)
|
v
lstatic CDN (lstatic.refrens.com/ceres/*)
|
v
User's browser

Caching rules

Not all files are cached the same way:

File typeCachingWhy
.js filesCached (with content hash or version in filename)They have unique names, so caching is safe
.css filesCached (same reason)Same, version in filename
.json filesNot cached (forced no-cache)Manifests need to update instantly when a new version is deployed
.html filesNot cached (forced no-cache)index.html should always be fresh

This setup means:

  • When you deploy a new template version, the manifest.json updates immediately
  • Browsers fetch the new manifest, see the new version path, and load the new JS/CSS
  • Old JS/CSS files can stay cached forever because they will never be referenced again

The deployment workflow

Deployment is handled by a GitHub Actions workflow at .github/workflows/deployCDN.yml. Here is what it does:

  1. Triggers on deployment event (not on push, deployment is triggered separately)
  2. Checks out the code
  3. Installs Node.js 22 and dependencies (npm ci)
  4. Builds everything (npm run build)
  5. Logs into Azure using credentials stored in GitHub secrets
  6. Uploads dist/ to Azure Blob Storage using az storage blob upload-batch
  7. (Optional) Purges the CDN cache if needed

The upload command looks like this:

az storage blob upload-batch \
--account-name $CERES_STORAGE_ACCOUNT \
--auth-mode key \
-d '$web/ceres' \
-s ./dist \
--overwrite

This uploads everything from dist/ into the $web/ceres container in Azure Blob Storage.