Câble ensemble le générateur (dépôt generator/) et le CMS Grav d'exemple (dépôt grav-reference/, monté :ro), tous deux clonés côte à côte et non versionnés ici. Contient : docker-compose dev + surcouche prod (rsync/SSH), image Grav (docker/grav), doc de câblage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
98 lines
4.6 KiB
Markdown
98 lines
4.6 KiB
Markdown
# portfolio-maker (stack)
|
||
|
||
Dépôt d'**orchestration** de l'environnement du générateur de portfolios PDF de
|
||
Figures Libres. Il ne contient pas de code applicatif : il câble ensemble, via
|
||
Docker Compose, l'app et le CMS Grav d'exemple qui lui sert de source de contenu.
|
||
|
||
## Trois dépôts, un environnement
|
||
|
||
Ce dépôt attend deux autres checkouts **posés côte à côte** (chacun a son propre
|
||
dépôt git et n'est pas versionné ici) :
|
||
|
||
```
|
||
portfolio-maker/ # CE dépôt (stack)
|
||
├── docker/grav/Dockerfile # Image PHP+Apache servant grav-reference/
|
||
├── docker-compose.yml # Services grav-reference (8089) + generator (8091)
|
||
├── docker-compose.prod.yml # Surcouche déploiement (build Nitro + rsync prod)
|
||
├── generator/ ←──────── dépôt À PART : l'app Nuxt (Dockerfile inclus) = le livrable
|
||
└── grav-reference/ ←──────── dépôt À PART : le vrai site Grav (~4,8 Go), monté :ro
|
||
```
|
||
|
||
- **`generator/`** — le générateur (Nuxt). Détails d'architecture : voir son propre
|
||
`README.md` / `CLAUDE.md`. Poussé sur le gitea figureslibres.io.
|
||
- **`grav-reference/`** — CMS Grav d'exemple, en **lecture seule** (monté `:ro`).
|
||
C'est la source de contenu, **pas** l'app à développer.
|
||
|
||
> ⚠️ Tout tourne dans Docker : Node, build Nuxt, Playwright/Chromium, Ghostscript,
|
||
> ffmpeg, rsync — rien n'est installé sur l'hôte.
|
||
|
||
> 📦 **Non versionné dans ce dépôt** : `generator/` et `grav-reference/` (dépôts
|
||
> séparés, à cloner côte à côte), ainsi que `docs/` (PDF de référence + spec déjà
|
||
> réalisée). Le `Dockerfile` de l'image Grav, lui, reste versionné dans `docker/grav/`.
|
||
|
||
## Lancer en dev
|
||
|
||
```bash
|
||
docker compose up -d # grav-reference + generator
|
||
```
|
||
|
||
- Grav de référence : http://localhost:8089
|
||
- Générateur de portfolios : http://localhost:8091 — mot de passe partagé :
|
||
`figureslibres` (variable `PORTFOLIO_PASSWORD`)
|
||
|
||
Le générateur lit directement `grav-reference/user/pages/02.projets/` (mode DEV
|
||
de `ContentSource`). Le bouton « Rafraîchir » relit le contenu local.
|
||
|
||
Commandes utiles (toujours via le conteneur) :
|
||
|
||
```bash
|
||
docker compose run --rm --no-deps generator npm install # dépendances
|
||
docker compose exec generator npm run build # build de prod
|
||
docker logs -f figureslibres-portfolio-generator # logs du dev server
|
||
```
|
||
|
||
## Parcours utilisateur
|
||
|
||
1. Se connecter (mot de passe partagé) — on arrive sur la liste des **portfolios**.
|
||
2. Créer un **portfolio** : ajouter des projets via la modale « Ajouter un
|
||
projet » (recherche plein texte, filtres catégorie/tag — seuls les projets
|
||
publiés sont proposés). Chaque projet = **deux pages ou plus**, fidèles au
|
||
gabarit `book_v3` (PDF de référence dans `docs/`, non versionné) :
|
||
- une page **couverture** : bandeau 55 mm couleur de la catégorie (titre en
|
||
fonte d'« utilité » — Playfair/Manifont/Avara —, pastille, présentation
|
||
Syne 12/16 pt) + image de couverture (celle de la grille du CMS) ;
|
||
- des pages **grille** : filet 5 mm, marges 8 mm, gouttières 3,8 mm, images
|
||
**entières** (jamais tronquées) calées sur la grille — 8 dispositions au
|
||
choix, présentées par icônes. Les vidéos ne sont pas sélectionnables.
|
||
Couleur de bandeau et texte noir/blanc réglables (palette du gabarit +
|
||
couleurs du site). Pages spéciales : couverture, sommaire, page libre.
|
||
Aperçu WYSIWYG A3 paysage, sauvegarde automatique.
|
||
3. **Générer le PDF** (nom de fichier personnalisable) : rendu Playwright/Chromium
|
||
au format **A3 paysage** (1190,55 × 841,89 pt, comme le gabarit), images
|
||
redimensionnées à 2× leur taille d'affichage (sharp), post-traitement
|
||
Ghostscript, métadonnées. Le contenu utilisé est **figé**
|
||
(`data/frozen/<id>/`) : régénérer redonne le même PDF ;
|
||
« Réactualiser depuis Grav » resynchronise volontairement.
|
||
|
||
## Déploiement (mode PROD)
|
||
|
||
Le contenu est tiré de la prod par **rsync/SSH en lecture seule** vers
|
||
`generator/data/content-cache/`, déclenché par le bouton « Rafraîchir ».
|
||
|
||
```bash
|
||
# .env (non versionné)
|
||
PORTFOLIO_PASSWORD=…
|
||
SESSION_SECRET=…
|
||
INTERNAL_TOKEN=…
|
||
SYNC_REMOTE=user@prod:/chemin/vers/user/pages/02.projets/
|
||
SYNC_SSH_KEY_FILE=/chemin/local/vers/cle_privee
|
||
|
||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d generator
|
||
```
|
||
|
||
## Données
|
||
|
||
Tout est sur disque dans `generator/data/` (sauvegarde = copie du dossier) :
|
||
`portfolios/*.json` (compositions), `exports/*.pdf`, `frozen/<id>/` (snapshots),
|
||
`cache/` (miniatures, posters vidéo — régénérable), `content-cache/` (rsync prod).
|