Plutôt que d'automatiser l'installation d'un site unique, une architecture séparant runtime, applications, données persistantes et mécanisme de déploiement — pensée pour maîtriser le cycle de vie de plusieurs sites Grav sans dupliquer leur exploitation.
Le premier besoin était relativement simple : automatiser le déploiement d'un site Grav utilisé comme documentation interne.
Mais ce site devait continuer à évoluer après son déploiement. Des pages seraient modifiées depuis l'interface d'administration, des images ajoutées, des comptes créés.
Un redéploiement de l'application ne devait donc jamais remettre le site dans son état initial et détruire les données produites en exploitation.
Une première frontière est apparue :
L'application doit pouvoir être remplacée. Les données utilisateur doivent survivre.
Le contenu persistant a donc été séparé du cycle de vie du conteneur.
Puis d'autres projets ont eu besoin de sites Grav. La question n'était alors plus : Comment déployer ce site ? mais :
Comment disposer d'un mécanisme permettant de déployer et maintenir plusieurs sites Grav sans dupliquer la logique d'exploitation ?
C'est à ce moment qu'un problème de déploiement est devenu un problème d'architecture.
Le contenu créé en exploitation doit survivre au remplacement d'un conteneur, à un redéploiement et à un changement de version.
La mécanique commune ne doit pas être copiée et adaptée pour chaque nouveau projet.
Runtime, application, données et déploiement n'évoluent ni au même rythme ni pour les mêmes raisons. Leur séparation doit refléter ces cycles de vie.
Revenir à une version précédente doit utiliser autant que possible le même mécanisme qu'un déploiement normal.
Les secrets et configurations sensibles restent hors des images applicatives et du code versionné.
L'analyse du premier déploiement puis l'arrivée de nouveaux projets ont fait apparaître quatre domaines distincts : runtime, application / site, données persistantes et mécanisme de déploiement. Les regrouper simplement parce qu'ils participent au même site aurait créé un couplage inutile. L'architecture cherche donc à rendre ces frontières explicites.
grav-runtime fournit la fondation technique commune : Grav, PHP, Nginx et le contrat attendu par les applications. Il ne connaît aucun projet métier particulier.
projet-gites, projet-lavallee-website et les futurs sites ajoutent uniquement ce qui leur est propre : thème, plugins, configuration applicative et contenu initial. Chaque application reste versionnée indépendamment.
ansible-role-grav-site centralise la mécanique commune : préparation de l'instance, volumes persistants, configuration, secrets, démarrage, contrôles de santé, mise à jour et rollback. Le rôle reste orienté vers une instance par invocation.
Pages, images, comptes et autres données persistantes vivent indépendamment de l'image applicative. Une nouvelle version peut donc remplacer l'application sans réinitialiser automatiquement son état de production.
Le premier déploiement a permis de formaliser une règle fondamentale : les éléments reconstruisibles appartiennent à l'application ; les données produites en exploitation doivent vivre en dehors du conteneur.
Grav, PHP, Nginx et les dépendances communes ont été isolés dans grav-runtime. Les projets applicatifs n'ont ainsi plus à reconstruire cette couche technique.
La mécanique d'exploitation a été regroupée dans ansible-role-grav-site : volumes, secrets, configuration, healthchecks, version déployée, update et rollback.
projet-gites, puis lavallee.tech, ont permis de confronter le modèle à plusieurs applications réelles. Le deuxième site a notamment exposé les hypothèses encore liées au premier projet — noms, chemins ou propriétés d'instance — et déclenché leur généralisation.
Une application n'est installée qu'une fois. Elle doit ensuite pouvoir être exploitée pendant des années. Le modèle recherché n'est donc plus :
install
mais :
deploy → update → rollback → migrate
Cette différence structure l'architecture. Le runtime est versionné. Chaque application est versionnée. Les données persistent indépendamment. Le mécanisme de déploiement applique l'état souhaité.
Le rollback n'est pas conçu comme une procédure d'urgence indépendante. Si une nouvelle version pose problème, une version précédente connue comme stable redevient simplement la version souhaitée.
version 1.3.2
│
▼
deploy 1.4.0
│
problème
│
▼
target = 1.3.2
│
▼
même mécanisme de déploiement
Cela limite les procédures spéciales précisément au moment où elles seraient les plus risquées : pendant un incident.
Le premier site a résolu un besoin. Le deuxième a commencé à tester l'architecture. Les suivants doivent pouvoir réutiliser le même socle sans multiplier la logique d'exploitation.
Il est facile de qualifier une architecture de « réutilisable » lorsqu'elle ne sert encore qu'un seul projet. Le deuxième consommateur révèle les hypothèses qui étaient en réalité spécifiques au premier.
lavallee.tech est désormais lui-même déployé sur cette architecture. Son arrivée a permis d'identifier les derniers paramètres d'instance qui doivent être généralisés pour que le rôle de déploiement reste un composant atomique et réutilisable.
La prochaine étape consiste à utiliser ce même mécanisme pour un nouveau site de documentation technique. La réutilisabilité n'est donc pas considérée comme une propriété déclarative.
Elle doit être vérifiée par de nouveaux consommateurs.
Le même socle — grav-runtime + ansible-role-grav-site — sera réutilisé sans modification pour ce nouveau consommateur, seule véritable preuve qu'une architecture est réutilisable.
L'utilisation de logiciels open source n'est qu'une partie du problème. Une infrastructure reste difficile à maîtriser si son déploiement dépend de manipulations manuelles, si ses données sont mélangées à l'application ou si personne ne sait précisément quelle version est en production.
Cette architecture cherche donc à rendre explicites :
L'open source est un moyen. La maîtrise du système est l'objectif.
La création de contenu et le design éditorial restent propres à chaque application.
Le rôle de déploiement ne gère ni DNS, ni reverse proxy, ni certificats TLS. Ces responsabilités appartiennent à l'infrastructure partagée.
La sauvegarde reste nécessaire. Grav évite d'exploiter un service de base de données supplémentaire, mais les fichiers persistants constituent des données de production et doivent être sauvegardés.
Le rôle de déploiement gère une instance par invocation. L'orchestration de plusieurs sites est volontairement traitée au niveau supérieur.
Les applications nécessitant des fonctionnalités métier complexes, un trafic important ou des modèles de données avancés peuvent sortir du périmètre naturel d'un CMS flat-file comme Grav.
Cette séparation n'est pas née d'un design théorique. Elle résulte de l'évolution d'un besoin concret : préserver les données d'un premier site, puis comprendre comment maintenir plusieurs applications sans dupliquer leur infrastructure.
Un déploiement automatisé n'est qu'une partie du problème. La vraie question est de savoir comment le système sera mis à jour, diagnostiqué, sauvegardé, restauré et transmis dans la durée.
Parlons d'abord de vos contraintes →