Reviewed-on: #4
Swansea Airport Website
Production-ready airfield website stack built with Astro, Directus, PostgreSQL, and Docker Compose.
Local setup
- Copy
.env.exampleto.envand fill in the values. - Start the stack with Docker Compose.
- Point your external Caddy instance at the frontend and Directus ports defined in
.env.
Services
- Frontend: Astro dev server running in a bind-mounted container for live preview
- CMS: Directus
- Database: PostgreSQL
- CMS bootstrap: one-shot schema initializer (
directus-bootstrap)
Notes
- All deploy-time variables live in
.env. PUBLIC_PPR_API_BASEcontrols the browser-side PPR API base URL; PPR and drone request endpoints are derived from it at build/dev-server startup.DIRECTUS_TOKENis the preferred read-only token for Astro content builds;DIRECTUS_ADMIN_TOKENis still used by Directus/bootstrap setup.DIRECTUS_DEBUG=truemakes Astro log Directus fetch/fallback reasons during builds.DIRECTUS_HOMEPAGE_BANNER_FOLDERnames the Directus file folder used for rotating homepage banner images. If the folder is missing or empty, the site falls back to/images/banner.png.- The frontend service bind-mounts the project into
/app, keepsnode_modulesand.astroin named volumes, and serves the site withastro devon the published frontend port. - Layout and page structure are controlled entirely by Astro.
- Frontend source edits should appear without rebuilding the container image.
- Cloudflare Worker deployment uses Wrangler static assets. See
docs/cloudflare-worker.mdfor the test/prod URL workflow.
Cloudflare Worker deployment
This project is normally developed through Docker Compose, so run the Worker build/deploy scripts inside the web service.
Copy the Worker env files first:
cp .env.worker.test.example .env.worker.test
cp .env.worker.prod.example .env.worker.prod
Build static files with the test URL set:
docker compose exec web npm run build:worker:test
Deploy the test build to the test Cloudflare Worker:
docker compose exec web npm run deploy:worker:test
Deploy production with the production URL set:
docker compose exec web npm run deploy:worker:prod
The deploy scripts build first, then upload dist/ with Wrangler. The test command uses .env.worker.test; the production command uses .env.worker.prod.
Programmatic Directus schema bootstrap
The schema bootstrap is automatic on docker compose up via the directus-bootstrap service.
It creates collections, fields, and core tag relations idempotently.
If the frontend dependency graph changes, restart the frontend container to rerun npm install inside the container volume:
docker compose up --build -d web
You can still run the script manually if needed:
docker compose run --rm directus-bootstrap
The bootstrap script is idempotent, so reruns are safe.
Troubleshooting bootstrap permissions
If you see 403 FORBIDDEN during bootstrap:
- Most commonly, the Directus database volume was initialized earlier with different admin credentials.
DIRECTUS_ADMIN_EMAILandDIRECTUS_ADMIN_PASSWORDare only used when Directus initializes a new database.- For stable bootstrap auth across restarts, set
DIRECTUS_ADMIN_TOKENin.envand keep it constant.
To start from a clean Directus state (development only):
docker compose down -v
docker compose up -d