Feature/gitea deployment workflow #1
@@ -286,20 +286,26 @@ Op een shared-hosting omgeving (zoals mijnhostingpartner.nl) is er meestal maar
|
||||
|
||||
| Pad | Inhoud |
|
||||
|---|---|
|
||||
| `/` | De publieke website van de klant — **geen onderdeel van deze repo**, wordt los aangeleverd/gedeployed in `wwwroot/` |
|
||||
| `/` | De publieke website van de klant, uit `wwwroot/web/` — **geen onderdeel van deze repo**. Zie [`WEBSITE_WORKSPACE.md`](WEBSITE_WORKSPACE.md) voor het volledige contract (verplichte structuur, verboden/gereserveerde paden, SPA-fallback, same-origin API-calls, CSP, Umami) |
|
||||
| `/admin` | De CMS admin-UI (`frontend/`), gebouwd met `base: '/admin/'` en automatisch gekopieerd naar `wwwroot/admin/` bij `dotnet publish` |
|
||||
| `/api/v1/...` | Deze API |
|
||||
| `/health` | Infrastructuur-liveness — zie "Health-check endpoint" hieronder |
|
||||
|
||||
Beide SPA's krijgen een fallback naar hun eigen `index.html` zodat client-side routes (bijv. `/admin/dashboard`) werken; ontbrekende bestanden (met een extensie, bijv. `/admin/assets/x.js`) blijven gewoon 404'en. Zie `Program.cs` (`MapFallbackToFile`) en `SlpModularCms.Api.csproj` (`BuildAndCopyAdminFrontend`-target).
|
||||
|
||||
Ontbreekt `wwwroot/web/` nog (een verse deployment vóórdat een website-workspace er iets in heeft gezet), dan start de applicatie gewoon door en toont `/` een ingebouwde placeholder-pagina — `/admin` en `/api/v1` blijven onverminderd werken.
|
||||
|
||||
Voor lokale ontwikkeling verandert er niets: `pnpm dev` blijft op `http://localhost:5173` draaien zonder `/admin`-prefix.
|
||||
|
||||
### 1. Build & Publish
|
||||
Compileer de applicatie voor productie — dit bouwt en kopieert automatisch ook de admin-frontend naar `wwwroot/admin/`:
|
||||
Publiceren gebeurt via de Gitea Actions-pipeline (`.gitea/workflows/continuous_integration.yaml` → `deploy-scp.yaml`), niet met een losse handmatige `dotnet publish`-stap: elke push naar `master` deployt automatisch naar test, productie alleen via een expliciete `workflow_dispatch` met de `deploy_production`-vlag aan. De pipeline publiceert framework-dependent voor `linux-arm64` en bouwt daarbij automatisch ook de admin-frontend mee naar `wwwroot/admin/`.
|
||||
|
||||
Elke deploy plaatst de nieuwe release in een verse map en wisselt pas daarna atomisch over naar `current` — er is dus nooit een moment waarop de applicatie een halfklare release serveert, en `wwwroot/web/` (de klantsite) staat structureel buiten die verwisselde map, zodat een deploy hem nooit kan raken. Volledige host-setup, rollback-procedure en de exacte deploy-stappen staan in de Operations-documentatie van deze feature, niet hier — dit README beschrijft alleen wat er gebouwd is, niet hoe je het voor het eerst inricht.
|
||||
|
||||
Wil je toch lokaal handmatig publiceren (bijv. om de output te inspecteren):
|
||||
```powershell
|
||||
dotnet publish src/SlpModularCms.Api -c Release -o ./publish
|
||||
dotnet publish src/SlpModularCms.Api -c Release -r linux-arm64 --self-contained false -o ./publish
|
||||
```
|
||||
Kopieer daarna de publieke website van de klant naar `./publish/wwwroot/` (alles behalve de `admin/`-submap, die blijft ongemoeid).
|
||||
|
||||
### 2. Runtime Configuratie
|
||||
In productie moeten gevoelige instellingen worden doorgegeven via Environment Variables:
|
||||
@@ -308,9 +314,14 @@ In productie moeten gevoelige instellingen worden doorgegeven via Environment Va
|
||||
- `JwtSettings__Issuer`
|
||||
- `JwtSettings__Audience`
|
||||
- `MasterModule__MasterUrl` — publieke URL van deze master-instantie (alleen relevant als de Master CMS Module actief is)
|
||||
- `Observability__SentryDsn` — leeg is een normale, ondersteunde staat: Sentry wordt dan overgeslagen en alleen console-logging blijft actief
|
||||
- `SecurityHeaders__AllowedScriptOrigins__0`, `SecurityHeaders__AllowedConnectOrigins__0`, ... — externe origins die de CSP van `/admin` en `/api/v1` mag toestaan (bijv. de Umami-scripthost en Sentry's ingest-endpoint). Zie `appsettings.json → SecurityHeaders` voor de volledige optiesvorm; een onbekende `PathPolicies`-policy-naam laat de applicatie bij **opstarten** falen, niet pas bij de eerste request
|
||||
|
||||
### 2a. Data Protection key ring (Master CMS Module)
|
||||
De API keys van geregistreerde slaves worden versleuteld opgeslagen met ASP.NET Core Data Protection, standaard met een bestandssysteem-key-store. Voor gecontaineriseerde of multi-instance deployments **moet** een persistente key ring geconfigureerd worden (bijv. `PersistKeysToDbContext` of `PersistKeysToAzureBlobStorage`). Zonder dit worden alle opgeslagen API keys onleesbaar zodra de container herstart, waardoor master↔slave-communicatie stopt totdat instanties opnieuw worden toegevoegd.
|
||||
De API keys van geregistreerde slaves worden versleuteld opgeslagen met ASP.NET Core Data Protection. De key ring wordt **automatisch** persistent opgeslagen in de database (`PersistKeysToDbContext`, met een expliciete, stabiele applicatie-discriminator) — dit hoeft niet meer apart geconfigureerd te worden. Dit is bewust zo gebouwd omdat de atomische release-switch (zie hierboven) bij elke deploy een nieuwe content-root-map gebruikt: zonder een database-backed key ring zou dat elke keer de key ring weggooien en alle opgeslagen slave-API-keys onleesbaar maken.
|
||||
|
||||
### 3. Database
|
||||
Zorg dat de doeltabel bestaat en de migraties zijn uitgevoerd. In productie kan dit via een CI/CD pipeline worden afgehandeld met `dotnet ef migrations script` of door de applicatie bij startup migraties te laten draaien (indien geconfigureerd).
|
||||
Migraties op `ApplicationDbContext` (Identity/Core) worden bij het opstarten **automatisch** toegepast (`MigrateCoreDatabase()`), en falen hard (fail-fast) als dat niet lukt — de applicatie start dan bewust niet door. Voor productie-deploys wordt vóór elke deploy een databasebackup genomen; zie de Operations-documentatie van deze feature voor de exacte procedure. Per-module migraties (`Modules.Master`, `Modules.Availability`) worden zoals voorheen automatisch toegepast via `UseModule` (zie "Per-module migraties" hierboven) — daar verandert niets aan.
|
||||
|
||||
### 4. Health-check endpoint
|
||||
`GET /health` geeft alleen **infrastructuur-liveness** aan ("draait het proces en kan het een basale response geven") — géén databasecheck, om te voorkomen dat het endpoint rood kleurt om redenen die niets met "leeft het proces nog" te maken hebben. Dit is expliciet **iets anders** dan `GET /api/v1/Availability/status` (de CMS-eigen aan/uit-schakelaar) of `GET /api/v1/System/capabilities` — een instantie kan gezond zijn en toch bewust uitgeschakeld, en andersom. `/health` staat op de bypass-lijst van `AvailabilityMiddleware`, zodat een uitgeschakelde instantie dit endpoint altijd blijft beantwoorden.
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# Website Workspace Contract
|
||||
|
||||
Dit document is voor wie de publieke website bouwt die naast de SlpModularCms-admin draait. Je hoeft
|
||||
de rest van deze repository niet te lezen om een werkende site te kunnen opleveren — dit contract is
|
||||
compleet genoeg om zelfstandig te volgen.
|
||||
|
||||
## Doelpad
|
||||
|
||||
De website hoort in **`wwwroot/web/`**, in de root van de gepubliceerde applicatie. Dit pad **moet**
|
||||
minimaal een `index.html` bevatten. Alles onder `wwwroot/web/` is van jou — de applicatie zelf raakt
|
||||
deze map nooit aan buiten het plaatsen van de bestanden die je aanlevert, en een CMS-deploy verwijdert
|
||||
of overschrijft de inhoud nooit (zie "Waarom dit veilig is" hieronder).
|
||||
|
||||
```
|
||||
wwwroot/
|
||||
web/ ← jouw site komt hier (dit contract)
|
||||
index.html ← verplicht
|
||||
assets/...
|
||||
...
|
||||
admin/ ← VERBODEN — dit is de CMS admin-UI, hoort niet bij deze repo
|
||||
```
|
||||
|
||||
## Verboden en gereserveerde paden
|
||||
|
||||
**Verboden** — plaats hier nooit bestanden:
|
||||
- `wwwroot/admin/` — dit is de CMS admin-single-page-app, wordt door deze repository zelf beheerd
|
||||
en bij elke build overschreven
|
||||
- De applicatie-root zelf (waar de `.dll`-bestanden van de API staan)
|
||||
|
||||
**Gereserveerd** — deze paden bestaan al en je site mag er niet mee botsen:
|
||||
- `/admin` — de CMS admin-UI
|
||||
- `/api/v1` — de backend-API
|
||||
- `/health` — infrastructuur-liveness-check (zie hieronder — dit is geen CMS-functionaliteit)
|
||||
|
||||
Als jouw site een eigen route of bestand op een van deze paden zou plaatsen, wint de gereserveerde
|
||||
route altijd.
|
||||
|
||||
## Routing (SPA-fallback)
|
||||
|
||||
Voor paden die **geen bestandsextensie** hebben (bijv. `/over-ons`, `/producten/123`) valt de
|
||||
applicatie terug op **`wwwroot/web/index.html`** — zo werkt client-side routing (React Router, Vue
|
||||
Router, of vergelijkbaar) zoals verwacht. Voor paden die er wél uitzien als een bestand (bijv.
|
||||
`/assets/logo.png`) geldt geen fallback: ontbreekt het bestand, dan krijg je gewoon een `404`, niet
|
||||
per ongeluk de `index.html`.
|
||||
|
||||
Dit betekent: bouw je een Single Page Application, dan hoeft je routing-configuratie niets speciaals
|
||||
te doen voor deze server — de fallback wordt door de applicatie zelf verzorgd.
|
||||
|
||||
## De API aanroepen
|
||||
|
||||
Roep `/api/v1/...` aan met **relatieve URL's** (bijv. `fetch('/api/v1/System/capabilities')`). Omdat
|
||||
je site en de API door hetzelfde proces op dezelfde origin worden geserveerd, is dit een **same-origin
|
||||
request** — er is geen CORS-configuratie nodig, en er hoeft niets ingesteld te worden om dit te laten
|
||||
werken.
|
||||
|
||||
## Content-Security-Policy
|
||||
|
||||
Jouw site valt onder het **`Relaxed`**-beleid (de standaardpolicy voor alle paden die niet expliciet
|
||||
`Strict` zijn — `/admin`, `/api/v1` en `/health` krijgen `Strict`, `/` (jouw site) niet). Dit beleid is
|
||||
bewust minder streng, zodat je niet gebonden bent aan restricties die voor de CMS-admin gelden maar
|
||||
die je als website-bouwer nooit zou hoeven kennen. De exacte permissieve/strikte policy-definities
|
||||
staan in code (`SlpModularCms.Core`), niet in configuratie — je hoeft ze niet zelf te lezen om te
|
||||
weten dat je site onder het permissieve beleid valt.
|
||||
|
||||
## Umami-analytics insluiten
|
||||
|
||||
Als de instantie analytics gebruikt, wordt het Umami-trackingscript geladen via een build-time
|
||||
omgevingsvariabele op de **admin**-kant (`VITE_UMAMI_SCRIPT_URL` / `VITE_UMAMI_WEBSITE_ID`) — dat
|
||||
script wordt dus niet door jouw site zelf ingesloten. Wil je dat jouw website ook gemeten wordt via
|
||||
dezelfde Umami-instantie, vraag dan de scriptregel en het bijbehorende website-ID op bij wie de CMS
|
||||
beheert, en neem die regel zelf op in je `index.html` (Umami's standaard `<script>`-snippet). Dit
|
||||
contract schrijft niets voor over jouw eigen analytics-keuze — dit is puur de informatie die je nodig
|
||||
hebt als je bij dezelfde Umami-instantie wilt aansluiten.
|
||||
|
||||
## Waarom dit veilig is
|
||||
|
||||
Een deploy van de CMS zelf gebeurt via een atomische release-switch: een nieuwe release komt in een
|
||||
verse map te staan en pas daarna wisselt de actieve release in één keer over. `wwwroot/web/` staat
|
||||
**buiten** die verwisselde map en wordt er telkens in gelinkt — een CMS-deploy kan je site dus
|
||||
structureel niet raken, ongeacht hoe vaak de CMS zelf wordt bijgewerkt.
|
||||
@@ -1148,3 +1148,36 @@ by Infrastructure Design. U5 carries REF-U3-01's Umami origin gate plus FR-21 an
|
||||
**Context**: CONSTRUCTION — Round 3 — U5 Code Generation complete, presenting completion message
|
||||
|
||||
---
|
||||
## Code Generation — U5 (Approved) / Round 3 Closed
|
||||
|
||||
**Timestamp**: 2026-07-28T01:45:00Z
|
||||
|
||||
**User Input**: "Continue to Next Stage"
|
||||
|
||||
**AI Response**: "U5 approved and committed (9f4ae47). Round 3 (U5 + U6) is now closed. Correcting the completion message's stated next step: Build and Test runs after ALL 7 units per the workflow's own rule, and U7 (Repository Documentation, Round 4) has not been generated yet — proceeding to Round 4 instead of Build and Test."
|
||||
|
||||
**Context**: CONSTRUCTION — Round 3 closed; entering Round 4 (U7)
|
||||
|
||||
---
|
||||
## Code Generation Plan — U7 Repository Documentation (Planning)
|
||||
|
||||
**Timestamp**: 2026-07-28T01:50:00Z
|
||||
|
||||
**User Input**: "(implicit — continuing after Round 3 closed)"
|
||||
|
||||
**AI Response**: "Created code generation plan for U7 (4 steps: WEBSITE_WORKSPACE.md contract, README.md updates, frontend/.env.example updates, accuracy verification against actual U1-U6 code). Presenting for approval before generation."
|
||||
|
||||
**Context**: CONSTRUCTION — Round 4 — U7 Code Generation Part 1, awaiting plan approval
|
||||
|
||||
---
|
||||
## Code Generation — U7 Repository Documentation (Complete)
|
||||
|
||||
**Timestamp**: 2026-07-28T02:00:00Z
|
||||
|
||||
**User Input**: "(implicit — plan approved, generation executed)"
|
||||
|
||||
**AI Response**: "Created WEBSITE_WORKSPACE.md (the FR-09 contract). Updated README.md's Production Setup section: new wwwroot/web/ layout with placeholder-on-missing behaviour, /health documented and distinguished from Availability/status, Build & Publish rewritten around the actual CI/CD pipeline, and — most notably — removed the now-outdated manual key-ring-configuration instruction since U2 already made it automatic. Updated frontend/.env.example with the same-origin default explanation and new observability variables. Verified every claim against actual U1-U6 source rather than the design record. No C# test project applies (documentation-only unit)."
|
||||
|
||||
**Context**: CONSTRUCTION — Round 4 — U7 Code Generation complete, presenting completion message
|
||||
|
||||
---
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
# Code Generation Plan — U7 Repository Documentation
|
||||
|
||||
## Unit Context
|
||||
|
||||
- **Unit**: U7 Repository Documentation (Documentation-only — no components, no code)
|
||||
- **Requirements**: FR-09
|
||||
- **Depends on**: U6 (settled host layout — `unit-of-work-dependency.md`: "U6 before U7 —
|
||||
documentation cannot precede the layout it documents")
|
||||
- **No Functional/NFR/Infrastructure Design, no test project**: per the execution plan, this unit
|
||||
goes straight to Code Generation
|
||||
- **Scope split** (Q8 of Requirements = A): repository documentation here; operational documents
|
||||
(host setup, rollback, FTPS switch) belong to the Operations phase, not this unit
|
||||
|
||||
## Steps
|
||||
|
||||
- [x] Step 1: Create `WEBSITE_WORKSPACE.md` at the repository root — the website workspace contract
|
||||
(FR-09): target path `wwwroot/web/` and required structure (must include `index.html`), forbidden
|
||||
paths (`wwwroot/admin/`, the application root), reserved paths (`/admin`, `/api/v1`, `/health`),
|
||||
SPA-fallback behaviour (non-file paths fall back to the website's own `index.html`; paths with a
|
||||
file extension 404 if missing), calling `/api/v1` same-origin with relative URLs (no CORS needed),
|
||||
which CSP policy applies to the public website (`Relaxed`, the default policy — `/admin`,
|
||||
`/api/v1` and `/health` get `Strict`) and what that permits, and how to include the Umami
|
||||
tracking script
|
||||
|
||||
- [x] Step 2: Update `README.md`
|
||||
- New `wwwroot` layout: `/` → `wwwroot/web/` (customer website, deployed separately, persists
|
||||
across releases), `/admin` → `wwwroot/admin/` (this repo's admin SPA), link to
|
||||
`WEBSITE_WORKSPACE.md` for the full contract
|
||||
- `/health` endpoint: what it proves (process liveness only) and what it explicitly does not mean
|
||||
(not the same as `Availability/status` or `System/capabilities`)
|
||||
- Production setup section rewritten for what U1–U6 actually built: CI/CD via Gitea Actions
|
||||
(`continuous_integration.yaml` → `deploy-scp.yaml`), atomic release switching, and the Data
|
||||
Protection key ring being automatic now (removing the old manual "you must configure a
|
||||
persistent key ring" instruction, since U2 already wires `PersistKeysToDbContext` by default)
|
||||
- New runtime configuration environment variables introduced by U3/U4: `SecurityHeaders__*`,
|
||||
`Observability__SentryDsn`, plus the frontend's `VITE_SENTRY_DSN` / `VITE_UMAMI_SCRIPT_URL` /
|
||||
`VITE_UMAMI_WEBSITE_ID`
|
||||
|
||||
- [x] Step 3: Update `frontend/.env.example`
|
||||
- Document the same-origin default: an absent or empty `VITE_API_BASE_URL` now means same-origin
|
||||
(the production default, since the SPA and API are served by one process); explicit absolute
|
||||
URLs still work unchanged for local development
|
||||
- Add the new observability variables: `VITE_SENTRY_DSN`, `VITE_APP_ENV`, `VITE_UMAMI_SCRIPT_URL`,
|
||||
`VITE_UMAMI_WEBSITE_ID`, each documented as optional/absent-is-supported
|
||||
|
||||
- [x] Step 4: Verify documentation accuracy against the code as built (Definition of Done)
|
||||
- Cross-checked every path, config key and behaviour claim against the actual U1–U6 source:
|
||||
`Program.cs` fallback/placeholder wiring, `SlpModularCms.Api.csproj`'s `BuildAndCopyAdminFrontend`
|
||||
and embedded `WebsitePlaceholder.html`, `AvailabilityMiddleware._bypassPrefixes`, U2's
|
||||
`MigrateCoreDatabase()` fail-fast and `PersistKeysToDbContext` discriminator, U3's
|
||||
`PathPolicies` fail-at-startup and `Relaxed`/`Strict` split in `appsettings.json`, U4's
|
||||
Sentry/Umami absent-is-supported behaviour, U6's `linux-arm64` framework-dependent publish and
|
||||
atomic release switch. No discrepancies found between the design record and what was actually
|
||||
built — all documentation claims verified directly against source
|
||||
|
||||
## Story / Requirement Traceability
|
||||
|
||||
| Step | Covers |
|
||||
|---|---|
|
||||
| 1 | FR-09 |
|
||||
| 2 | FR-07, FR-08, FR-10 (documented, not re-implemented), FR-12 (key ring note) |
|
||||
| 3 | FR-13, FR-14, FR-15, FR-16 (documented, not re-implemented) |
|
||||
| 4 | Definition of Done: "documentation is accurate against the code as built in U1–U6" |
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
# Code Generation Summary — U7 Repository Documentation
|
||||
|
||||
**Date**: 2026-07-28
|
||||
|
||||
## Files Created
|
||||
|
||||
- `WEBSITE_WORKSPACE.md` — the website workspace contract (FR-09): target path, required structure,
|
||||
forbidden/reserved paths, SPA-fallback behaviour, same-origin `/api/v1` calls, applicable CSP
|
||||
policy, Umami inclusion, and why the atomic release switch can't touch it
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `README.md` — "Productie Setup" section rewritten:
|
||||
- `/` now documented as `wwwroot/web/`, linking to `WEBSITE_WORKSPACE.md`; noted that a missing
|
||||
`wwwroot/web/` at startup serves a built-in placeholder rather than failing
|
||||
- New `/health` row and a dedicated "Health-check endpoint" subsection distinguishing liveness
|
||||
from `Availability/status` / `System/capabilities`
|
||||
- "Build & Publish" rewritten around the actual Gitea Actions pipeline (push → automatic test
|
||||
deploy, `workflow_dispatch` + flag → production) instead of a bare manual `dotnet publish`
|
||||
- New runtime configuration entries: `Observability__SentryDsn`,
|
||||
`SecurityHeaders__AllowedScriptOrigins__0` / `AllowedConnectOrigins__0`
|
||||
- **§2a rewritten**: removed the outdated instruction to manually configure a persistent Data
|
||||
Protection key ring — U2 already made this automatic (`PersistKeysToDbContext` with an explicit
|
||||
discriminator), so the README no longer tells the reader to do work that's already done
|
||||
- **§3 rewritten**: documented the automatic, fail-fast `ApplicationDbContext` migration at
|
||||
startup and the pre-production backup, replacing the old "can be handled via a CI/CD pipeline"
|
||||
hand-wave with what's actually built
|
||||
- `frontend/.env.example` — documented the same-origin default for `VITE_API_BASE_URL`; added
|
||||
`VITE_SENTRY_DSN`, `VITE_APP_ENV`, `VITE_UMAMI_SCRIPT_URL`, `VITE_UMAMI_WEBSITE_ID`, each noted as
|
||||
optional
|
||||
|
||||
## Verification (Step 13.5 — this unit's own check)
|
||||
|
||||
No code, no test project — this is a documentation-only unit (same as its "no components" listing
|
||||
in `unit-of-work.md`). Every factual claim was checked directly against source rather than against
|
||||
the design record (see Step 4 in the code generation plan for the full checklist): `Program.cs`,
|
||||
`SlpModularCms.Api.csproj`, `AvailabilityMiddleware`, U2's Data Protection extensions, U3's
|
||||
`SecurityHeadersOptions` validation, U4's Sentry/Umami configuration, and U6's infrastructure design
|
||||
for the publish/deploy specifics. No discrepancies found.
|
||||
|
||||
## Deferred to Operations (not built here, by design — Q8 of Requirements = A)
|
||||
|
||||
- Host setup instructions, the rollback procedure, and the FTPS switch path (FR-23)
|
||||
- Actual Gitea variable/secret values
|
||||
- UptimeRobot, Sentry alert rules, and the `dotnet-appsettings` compliance gate
|
||||
@@ -1,4 +1,9 @@
|
||||
# Base URL of the SlpModularCms .NET API.
|
||||
#
|
||||
# Leave this empty (or unset) for the production default: the SPA and the API are served by the
|
||||
# same process, so an empty value means same-origin — requests use relative paths and no CORS
|
||||
# configuration is needed at all. An explicit absolute URL is still honoured and required for local
|
||||
# development, where the frontend dev server and the backend run on different ports:
|
||||
# The backend must be running with CORS configured to allow this origin
|
||||
# and to send the httpOnly refresh-token cookie (credentials: include).
|
||||
# Set CookieSameSite=None in appsettings.Development.json so the cookie
|
||||
@@ -10,6 +15,21 @@ VITE_API_BASE_URL=https://localhost:7221
|
||||
# (e.g. local master vs. slave, see below).
|
||||
VITE_APP_TITLE=SlpModularCms
|
||||
|
||||
# --- Observability (all optional — absent is a supported state, not an error) ---
|
||||
|
||||
# Sentry DSN for the admin SPA. Absent or empty skips Sentry initialisation entirely; only console
|
||||
# logging remains active. Not sensitive — safe to expose in the client bundle.
|
||||
VITE_SENTRY_DSN=
|
||||
|
||||
# Environment tag attached to Sentry events (e.g. "test", "production"). Set per-environment by the
|
||||
# CI pipeline (see .gitea/workflows/continuous_integration.yaml) — leave empty for local development.
|
||||
VITE_APP_ENV=
|
||||
|
||||
# Umami analytics script host and this environment's website ID. Both absent means the Umami
|
||||
# component renders nothing — leave unset for local development.
|
||||
VITE_UMAMI_SCRIPT_URL=
|
||||
VITE_UMAMI_WEBSITE_ID=
|
||||
|
||||
# --- Local master/slave dev setup ---
|
||||
# To point the frontend at the slave instance (SlpModularCms.Api.Slave,
|
||||
# see root README.md "Lokaal Master + Slave Draaien (Dev)") instead of the
|
||||
|
||||
Reference in New Issue
Block a user