Skip to content

Build, base de donnees, uSync, deploiement

Spécificité intranet PEL (15.07.2026) : l'hébergement de production sera Windows IIS chez Pully, pas le pipeline Docker Linux décrit ci-dessous (qui reste valable pour un éventuel staging Spektrum). Déploiement IIS : dotnet publish + ASP.NET Core Module (modalités exactes — WebDeploy/zip, pool, in-process — à préciser au compte-rendu du SSI). Conséquence fonctionnelle : le SSO Windows Authentication est possible (voir domain/business-rules.md, section Intranet & AD).

Build

  • Backend : dotnet build Sentinelle.sln (.NET 10) construit les 5 projets de la solution : Web (executable), Intranet.Core, Intranet.Connectivity (bibliotheques referencees par Web, voir overview.md), Tests.Common, Tests.Web. dotnet run --project src/Web/Web.csproj pour lancer en local - seul Web est executable.
  • Frontend : depuis src/Web, npm ci + npm run build:prod (lint + Vite prod). Voir frontend-build.md.
  • Web.csproj : CopyRazorGenerateFilesToPublishDirectory=true (vues backoffice), rewriteRules.xml copie en sortie/publish (PreserveNewest), ICU app-local (Microsoft.ICU.ICU4C.Runtime), ProjectReference vers Intranet.Core et Intranet.Connectivity. dotnet publish sur Web.csproj publie transitivement les deux.

Base de donnees

  • SQL Server. Chaine par defaut (appsettings.json) : Server=localhost\sqlexpress;Database=UmbracoBaseTemplate;User Id=dev;Password=dev;TrustServerCertificate=true;, provider Microsoft.Data.SqlClient.
  • Override par appsettings.local.json (git-ignore) ou variable d'env.
  • Umbraco:CMS:Unattended:UpgradeUnattended=true : Umbraco applique les migrations au boot (pas de restauration manuelle ni d'etape d'install).

uSync

  • uSync 17.3.5. Config serialisee sous src/Web/uSync/v17/ (ContentTypes, DataTypes, Dictionary, Languages, MediaTypes, MemberTypes, Templates).
  • Reglages (appsettings.json) : ExportOnSave="Settings", ImportAtStartup="Settings", UIEnabledGroups="Settings". Le handler Dictionnaire est en CreateOnly (les traductions ne sont pas ecrasees a l'import).
  • Workflow : modifier dans le backoffice -> uSync exporte les .config ; au demarrage, uSync importe le groupe Settings.

Docker

hosting/Dockerfile (build multi-stage, build depuis la racine du repo, pas depuis hosting/) — 3 stages :

  1. frontend (node:22.12.0-slim) : npm ci puis npm run build:prod (lint ESLint + Vite prod). Copie scripts/, styles/ et Views/ (les vues .cshtml sont le contenu PurgeCSS ; sans elles PurgeCSS purge tout le CSS), plus vite.config*.js et eslint.config.js. Sortie : wwwroot/css/<theme>/main.css + wwwroot/js/.
  2. build (dotnet/sdk:10.0) : COPY ./src/ ./ (tout le dossier src/, et non plus seulement src/Web/ - depuis le split en 3 projets, Web reference Intranet.Core/Intranet.Connectivity par ProjectReference relatif, dotnet restore/publish a besoin des .csproj des trois), puis WORKDIR /src/Web avant d'ecraser wwwroot/css/wwwroot/js avec la sortie du stage frontend, dotnet restore + dotnet publish -c Release -o /app/publish (execute depuis Web.csproj, publie transitivement Intranet.Core/Intranet.Connectivity).
  3. runtime (dotnet/sdk:10.0) : copie /app/publish, ENTRYPOINT ["dotnet", "Web.dll"].

Non verifie : ce changement de contexte de build (COPY ./src/ au lieu de COPY ./src/Web/, WORKDIR /src/Web ajoute avant dotnet restore) accompagne le split en 3 projets mais n'a pas ete valide par un docker build reel dans cette tache - a executer avant le premier deploiement qui suit le split.

Point de vigilance - pas de .dockerignore : le repo n'a aucun .dockerignore. COPY ./src/ ./ embarque donc aussi les bin//obj/ des trois projets (Web, Intranet.Core, Intranet.Connectivity) s'ils existent localement au moment du build, ce qui alourdit le contexte envoye au daemon Docker et peut, dans de rares cas, faire fuiter des artefacts de build locaux dans l'image intermediaire. Purger bin/obj avant un docker build local, ou ajouter un .dockerignore (**/bin/, **/obj/).

Build / push (registry interne registry.internal.spektrum-suisse.ch, sans authentification) :

bash
docker build -t registry.internal.spektrum-suisse.ch/sentinelle-website:<tag> -f hosting/Dockerfile .
docker push registry.internal.spektrum-suisse.ch/sentinelle-website:<tag>

<tag> = staging (branche staging) ou prod (branche master). Le pipeline pousse aussi un tag :$CI_COMMIT_SHORT_SHA par commit.

Version affichee dans le dashboard "Système" : les ARG/ENV GIT_COMMIT_* du stage runtime alimentent la boite "Version & build" du backoffice (voir modules/backoffice.md). Pour renseigner la version au build, passer les infos git en --build-arg :

bash
docker build \
  --build-arg GIT_COMMIT_COUNT="$(git rev-list --count HEAD)" \
  --build-arg GIT_COMMIT_SHA="$(git rev-parse --short HEAD)" \
  --build-arg GIT_COMMIT_DATE="$(git log -1 --format=%cI)" \
  -t columbia-registry.spektrum.media/umb_<site>:<env> -f hosting/Dockerfile .

Sans ces --build-arg, la version tombe sur 1.0.0.dev (l'image runtime aspnet:10.0 ne contient pas git : aucun fallback CLI, la version vient uniquement des env vars). Le .gitlab-ci.yml du template ne construit pas d'image Docker (build/push manuels) : il n'y a donc pas de job CI ou passer ces build-args. Un projet aval qui ajoute un job docker en CI doit y injecter les --build-arg lui-meme.

hosting/docker-compose.yml (exemple a adapter, placeholders <mon-site>/<env>/<mon-port-externe>) : monte appsettings.json (ro), media/, logs/ en volumes, reseau externe app-network, ASPNETCORE_ENVIRONMENT=Staging, ASPNETCORE_URLS=http://*:5000, forwarded headers actives.

CI/CD (GitLab)

.gitlab-ci.yml. Trois stages : build, deploy, docs.

Validation (stage build, merge requests uniquement, rules: CI_PIPELINE_SOURCE == "merge_request_event") :

  • build:backend : image dotnet/sdk:10.0, dotnet build Sentinelle.sln --configuration Release.
  • build:frontend : image node:22.12.0, cd src/Web && npm ci && npm run build:prod.

Deploiement Docker (stage deploy, docker:25 + service docker:25-dind, tag runner linux) — construit et pousse l'image registry.internal.spektrum-suisse.ch/sentinelle-website (registry sans auth, pas de docker login). Template .deploy_template : docker pull du tag de cache, docker build --cache-from, puis push du tag primaire ET du $CI_COMMIT_SHORT_SHA.

  • deploy:staging : push sur la branche staging -> tag :staging.
  • deploy:production : push sur la branche master -> tag :prod.

workflow.rules autorise le pipeline pour : merge requests ciblant master, commits sur master, commits sur staging.

Un bloc docs (composant sync-claude-docs) synchronise .claude/docs/** vers le site de doc interne sur master/main/staging (gate sur changements de .claude/docs/**).

Sentry

Charge uniquement en Staging/Production et si SentryUrl est defini (appsettings.json, vide par defaut, a injecter sans le committer). Prod : TracesSampleRate=0.1. Staging : ProfilingIntegration a 500 ms et Debug=true.

URL rewrites

src/Web/rewriteRules.xml (format IIS) applique via app.UseRewriter() en Staging/Production uniquement.

Déploiement APOL - Entra ID (M365)

Variables propres à un déploiement APOL (skin Entra ID, voir modules/extensibility.md et domain/business-rules.md). Section absente = brique inerte (comme Ldap pour PEL) ; ne pas la configurer en local.

  • Section EntraId (appsettings.<Env>.json ou variables d'env) : TenantId, ClientId, CallbackPath (garder la valeur par défaut /umbraco-entra-members-signin sauf besoin explicite - un changement doit être répercuté dans l'allowlist de MemberGateMiddleware).
  • Secret ClientSecret : jamais committé, via appsettings.local.json (git-ignore) ou variable d'env EntraId__ClientSecret, comme Ldap__ServicePassword.
  • App Registration Entra : l'URI de redirection déclarée côté Azure/Entra doit correspondre exactement à CallbackPath (https://<host-apol>/umbraco-entra-members-signin).
  • Intranet:LoginPath=/account/microsoft (point d'entrée du challenge OAuth, remplace /login utilisé côté PEL) et Intranet:RequireLogin=true.

Exemple de config :

json
"EntraId": {
  "TenantId": "<tenant-guid-apol>",
  "ClientId": "<client-id-app-registration>",
  "CallbackPath": "/umbraco-entra-members-signin"
},
"Intranet": { "RequireLogin": true, "LoginPath": "/account/microsoft" }

Breaking change Umbraco 17.4 - URL applicative

Depuis 17.4, la detection auto de l'URL via le header Host est optionnelle (risque de spoofing sur emails de reset/invitation). Le template fournit une section vide Umbraco:CMS:WebRouting:UmbracoApplicationUrl. Tout projet aval derriere un reverse proxy doit la renseigner (appsettings de prod ou variable d'env Umbraco__CMS__WebRouting__UmbracoApplicationUrl).

Contributors

No contributors

Changelog

No recent changes