Déploiement du business-dashboard
Cette page décrit comment le portail web destiné aux marchands et aux équipes organisations (apps/business-dashboard) est construit, déployé et hébergé.
URLs publiques
| Environnement | URL publique | URL Firebase brute |
|---|---|---|
| Staging / prod | https://business.paywithnex.com | https://business-dashboard-nex.web.app |
| Review | https://business-review.paywithnex.com | https://business-review-nex.web.app |
Stack
| Élément | Choix |
|---|---|
| Source | apps/business-dashboard/ (Nuxt 4 SPA) |
| Mode rendu | ssr: false → SPA static (pas de Nitro server) |
| Output build | apps/business-dashboard/.output/public/ |
| Build | pnpm --filter @nex/business-dashboard build |
| Hébergement | Firebase Hosting, projet GCP dédié business-dashboard-nex (≠ cmms-dashboard pour isolation de domaine) |
| CDN | Edge Firebase (Google) |
| TLS | Let's Encrypt auto via Firebase (custom domain) |
| DNS | Zone paywithnex.com (Cloudflare) |
Sites Firebase
Le projet business-dashboard-nex contient 2 sites Hosting, un par environnement :
Target .firebaserc | Site Firebase | Usage |
|---|---|---|
staging | business-dashboard-nex (default site) | Build de la branche main, custom domain business.paywithnex.com |
review | business-review-nex (USER_SITE) | Build de la branche develop, custom domain business-review.paywithnex.com |
Mapping dans apps/business-dashboard/.firebaserc.
Pipeline GitLab CI
Deux jobs dans infrastructure/cicd/deploy-business-dashboard.yml :
| Job | Branche | Trigger | Target Firebase |
|---|---|---|---|
deploy-review:business-dashboard | develop | manual (allow_failure) | business-review-nex |
deploy-staging:business-dashboard | main | manual (allow_failure) | business-dashboard-nex |
Filtres changes: pour ne déclencher le job que si apps/business-dashboard/**, packages/** ou pnpm-lock.yaml a changé — évite de re-déployer pour chaque push qui touche un autre périmètre.
Template partagé
Le template .deploy-business-dashboard-base (dans _templates.yml) fait :
pnpm installdu workspace BD + des packages partagés (shared-types,shared-utils,tokens)- Build topologique des packages partagés (
shared-types→shared-utilsà cause des.d.tsimports) pnpm --filter @nex/business-dashboard build(Nuxt SPA static →.output/public/)firebase deploy --only "hosting:${FIREBASE_TARGET}"vers le projetbusiness-dashboard-nex
Variables d'env (CI/CD GitLab)
| Variable | Provenance | Description |
|---|---|---|
FIREBASE_SERVICE_ACCOUNT_BUSINESS_DASHBOARD | Doppler paywithnex/stg | JSON du service account gitlab-ci-deployer@business-dashboard-nex.iam.gserviceaccount.com (roles : firebasehosting.admin + firebase.developAdmin). |
API_BASE_URL | définie dans le job | URL nginx ingress de l'env (review/staging) où le BD envoie ses appels /api/*. |
CMMS_URL | définie dans le job | URL du CMMS — utilisé pour le lien "mot de passe oublié" qui pointe sur le flow reset existant. |
Variables consommées au build
Le BD est en mode SPA (ssr: false). Les runtimeConfig.public.* sont embeddées dans le bundle JS au moment du nuxt build. Changer une URL côté Doppler ou GitLab ne suffit pas — il faut re-déclencher le pipeline pour que la valeur soit injectée dans un nouveau bundle.
Provisioning initial
Création projet Firebase + sites
Effectué une seule fois (déjà fait, ici pour traçabilité) :
gcloud projects create business-dashboard-nex --name="Business Dashboard"
gcloud services enable firebase.googleapis.com firebasehosting.googleapis.com --project=business-dashboard-nex
# Ajout du projet à Firebase via console UI ou Firebase CLI
firebase hosting:sites:create business-review-nex --project business-dashboard-nexLe default site business-dashboard-nex est créé automatiquement quand Firebase est activé sur le projet.
Service account CI
gcloud iam service-accounts create gitlab-ci-deployer \
--display-name="GitLab CI Deployer" \
--project=business-dashboard-nex
gcloud projects add-iam-policy-binding business-dashboard-nex \
--member="serviceAccount:gitlab-ci-deployer@business-dashboard-nex.iam.gserviceaccount.com" \
--role="roles/firebasehosting.admin" --condition=None
gcloud iam service-accounts keys create /tmp/key.json \
--iam-account=gitlab-ci-deployer@business-dashboard-nex.iam.gserviceaccount.com \
--project=business-dashboard-nex
# Upload dans Doppler
doppler secrets set FIREBASE_SERVICE_ACCOUNT_BUSINESS_DASHBOARD="$(cat /tmp/key.json)" \
--project paywithnex --config stg
rm /tmp/key.jsonCustom domain
Les deux sites ont un custom domain dédié, provisionné via Firebase Console :
| Site Firebase | Custom domain | Console URL |
|---|---|---|
business-dashboard-nex (staging/prod) | business.paywithnex.com | console.firebase.google.com/... |
business-review-nex (review) | business-review.paywithnex.com | console.firebase.google.com/... |
Pour chaque site : Add custom domain → entrer le sous-domaine. Firebase donne :
- 1 TXT record pour vérifier la propriété du domaine (
firebase-attestation=...) - 2 A records (IPs Firebase Hosting) pour le routing du trafic HTTP/HTTPS
Ces records sont créés côté Cloudflare DNS (zone paywithnex.com) en mode unproxied (icône grise — sinon Cloudflare intercepte le TXT et Firebase n'arrive pas à valider). Après ~15-30 min, Firebase valide et provisionne le certificat Let's Encrypt automatiquement.
Procédure de déploiement manuel
Déployer en review (depuis develop)
- Merger la MR dans
develop - Aller dans GitLab → Pipelines → dernier pipeline
develop - Cliquer manuellement sur le job
deploy-review:business-dashboard - Suivre les logs (~3-5 min, build + deploy Firebase)
- Vérifier sur https://business-review.paywithnex.com
Déployer en staging (depuis main)
Idem mais sur la branche main → job deploy-staging:business-dashboard → vérifier sur https://business.paywithnex.com.
Troubleshooting
Le build CI échoue avec "Cannot find module '@nex/shared-types'"
Causé par un ordre topologique cassé. Le template fait toujours pnpm --filter "@nex/shared-types" --filter "@nex/shared-utils" --filter "@nex/tokens" run build avant le build BD. Si l'un de ces packages n'a pas de script build, l'erreur surgit.
Firebase deploy échoue "Permission denied"
Le service account gitlab-ci-deployer a perdu son rôle firebasehosting.admin. Re-binder :
gcloud projects add-iam-policy-binding business-dashboard-nex \
--member="serviceAccount:gitlab-ci-deployer@business-dashboard-nex.iam.gserviceaccount.com" \
--role="roles/firebasehosting.admin" --condition=NonePage blanche après déploiement, console JS : "Cannot connect to API"
Vérifier que le bundle déployé contient la bonne API_BASE_URL. Si tu vois localhost:8080/api, c'est qu'un build local a été déployé par erreur ou que la variable n'est pas posée dans le job CI. Re-trigger le pipeline avec les bonnes vars.
Custom domain "needs setup" depuis 1h
Firebase n'arrive pas à valider le TXT record. Vérifier côté Cloudflare que le record est bien unproxied (icône grise, pas orange — sinon Cloudflare cache le TXT et Firebase ne voit rien). Re-déclencher la verification dans Firebase Console.
Voir aussi
- Déploiement de la doc — autre site Firebase, projet
cmms-dashboard - Pipelines CI/CD — vue d'ensemble des pipelines GitLab
- Variables et stack — convention
.envet secrets Doppler