Files
egfh-website/docs/cloudflare-worker.md
2026-06-21 09:33:54 -04:00

5.4 KiB

Cloudflare Worker Static Assets

This project uses Astro static output, so Cloudflare only needs the generated dist/ directory.

The public site is deployed as a Cloudflare Worker serving static assets. Wrangler supports deploying a directory of static assets with wrangler deploy dist.

URL Sets

Keep three sets of URLs separate:

  • Local development: .env, used by Docker Compose and astro dev.
  • Test Worker deployment: .env.worker.test, used by npm run build:worker:test and npm run deploy:worker:test.
  • Production Worker deployment: .env.worker.prod, used by npm run build:worker:prod and npm run deploy:worker:prod.

The important distinction is that Astro fetches Directus content during the build. The URLs in the env file selected for the build are baked into the generated static files.

First-Time Setup

Copy the example files and fill in the real values:

cp .env.worker.test.example .env.worker.test
cp .env.worker.prod.example .env.worker.prod

Do not commit .env.worker.test or .env.worker.prod; they contain API tokens.

Create a Cloudflare API token that can deploy Workers, then set these values in both env files:

CLOUDFLARE_ACCOUNT_ID=...
CLOUDFLARE_API_TOKEN=...

In practice, Wrangler's static asset upload currently works reliably with a user-owned API token scoped to the target account. Account-owned tokens may authenticate successfully with wrangler whoami but still fail during workers/scripts/<name>/assets-upload-session with Authentication error [code: 10000].

For a user-owned token, start with these permissions:

Account -> Workers Scripts -> Edit
Account -> Account Settings -> Read
User -> Memberships -> Read

If the deploy command manages Worker routes or domains, also grant the matching zone/worker route permissions for the target domain.

Each env file also names the target Worker:

CF_WORKER_NAME=swansea-airfield-test

For Directus, use public HTTPS URLs in Worker env files. Do not use Docker-only hostnames such as http://directus:8055 outside Docker Compose.

Use DIRECTUS_TOKEN for the read-only token Astro uses at build time. DIRECTUS_ADMIN_TOKEN is still supported for older local setups, but production/test deploy files should prefer DIRECTUS_TOKEN.

To make Astro print Directus fetch diagnostics during a build, set:

DIRECTUS_DEBUG=true

This logs collection reads, folder/file reads, and the reason an image folder fell back to bundled images.

For image-backed pages, the build token needs read access to:

news
events
event_dates
event_templates
notices
fuel_prices
documents
contacts
directus_files
directus_folders

The homepage and cafe image rotators specifically call /folders and /files, so directus_folders read permission is required in addition to directus_files.

Directus Assets From R2

Local development can keep using Directus asset URLs. For test and production Worker builds, set one of these optional values in .env.worker.test and .env.worker.prod to make the generated Astro HTML point at R2-hosted files instead:

DIRECTUS_ASSET_BASE_URL=https://assets.swansea-airport.wales/

With DIRECTUS_ASSET_BASE_URL, a Directus file ID such as abc-123 becomes:

https://assets.swansea-airport.wales/abc-123.jpeg

The extension comes from Directus filename_download, so R2 object keys should use the pattern <directus-file-id>.<extension>.

If the R2 public URL needs a custom path shape, use a template instead:

DIRECTUS_ASSET_URL_TEMPLATE=https://assets.swansea-airport.wales/directus/{id}

DIRECTUS_ASSET_URL_TEMPLATE takes priority over DIRECTUS_ASSET_BASE_URL. The template supports {id}, {key}, and {fileId} as aliases for the R2 object key, usually Directus filename_disk. Leave both unset in local .env to keep using DIRECTUS_PUBLIC_URL/assets/<id>.

Build Locally For Test

When working through Docker Compose:

docker compose exec web npm run build:worker:test

This loads .env.worker.test, fetches content from the test Directus URL, and writes static files to dist/.

Deploy To The Test Worker

docker compose exec web npm run deploy:worker:test

This builds with .env.worker.test, then uploads dist/ to the Worker named by CF_WORKER_NAME.

Deploy To The Production Worker

docker compose exec web npm run deploy:worker:prod

This builds with .env.worker.prod, then uploads dist/ to the production Worker.

Routes And Domains

The deploy wrapper can optionally attach a route or custom domain if the env file sets one of these:

CF_WORKER_ROUTE=swansea-airport.wales/*
CF_WORKER_DOMAIN=swansea-airport.wales

Leave both unset if routes/domains are managed in the Cloudflare dashboard.

Gitea CI Shape

In Gitea Actions, create the selected env file from CI secrets, then run:

npm ci
npm run deploy:worker:prod

The deploy script treats the selected env file as the source of truth. This is deliberate because the Docker Compose web service already has local development variables in its environment, and production/test deploys need to override them.

Content Updates

Static deploys are snapshots. If Directus content changes after deployment, the Worker will not update until another build and deploy runs.

For production, trigger npm run deploy:worker:prod from either:

  • a code push to Gitea,
  • a manual Gitea Actions workflow,
  • a Directus webhook that calls your CI runner,
  • or a scheduled CI job.