deployment/cloud: PocketBase (pinned, sha256-checked) as dev (/pb/, signed in; its /_/ dashboard for OIDC_ADMIN_GROUPS only) and prod (/api-prod/api/ public, dashboard never exposed), with the schema as migrations in backend/pocketbase/pb_migrations and data on the /data volume; superuser from env. admin.mjs routes /cdn/, /api-prod/, /pb/ and /admin/ behind oauth2-proxy (public: /cdn/ and /api-prod/api/ only). build-cdn.sh: flock (409 on a second build), a snapshot of the pulled commit, the public exclusions applied BEFORE the build, a heap-capped build, a check of the output that REFUSES the swap if anything excluded remains (proved with planted fixtures: a field-access file, 'Visa Requirements' content, and key-cities one level down each fail; clean passes), then an atomic swap; runtime-config.js carries the public API URL. public-exclusions.txt is the ONE list the giveaway export and the CDN build share. Any git host via REPO_URL/BRANCH/GIT_TOKEN. |
||
|---|---|---|
| .. | ||
| pb_migrations | ||
| README.md | ||
PocketBase — the backend for plugins that need one
The cloud container (deployment/cloud) runs two PocketBase
instances: dev (behind the team sign-in, for building) and prod (its /api/ public, for
published plugins). Both apply the migrations in pb_migrations/ on start, so
the schema lives in git and publishing never copies data from dev to prod.
A plugin reads its backend address at runtime (profile-config apiBase, or
window.MAP_API_BASE set by the published build's runtime-config.js), so moving the backend never
needs a rebuild.
v1 limits: collection rules are the only access control (lock collections by default); no per-plugin isolation between plugin authors yet.