Portfolio — architecture
Stack proposée (ADRs 001 et 002) : Astro + Tailwind CSS, site 100 % statique servi par nginx, déployé par la chaîne CI/CD standard.
Briques écartées par principe (YAGNI)
| Brique | Pourquoi absente du MVP |
|---|---|
| Base de données | Le contenu est en fichiers versionnés — rien à stocker |
| Authentification / backend | Site public en lecture seule, contact par liens |
| Cache, files, e-mails | Aucun traitement serveur |
Si un besoin futur les justifie (ex. formulaire), un ADR instruira la décision à ce moment-là.
Flux de bout en bout
flowchart LR
subgraph Poste["dev-laravel (poste)"]
C["Contenu + code\n(collections .md, pages .astro)"]
end
subgraph Forge["Forgejo (CT 110)"]
G["repo leon/portfolio\nGitflow main/develop"]
end
subgraph CI["Woodpecker (CT 111)"]
V["commits-conformes\n+ build Astro (test)"]
T["version-semver\n(tag vX.Y.Z sur main)"]
end
subgraph Prod["VM 101 Coolify"]
B["Build Dockerfile :\nAstro build → nginx"]
S["Site statique"]
end
C -- "git flow / cz commit" --> G
G -- webhook --> V
V -- "si vert, push main" --> T
V -- "API deploy (main)" --> B
B --> S
G -. "miroir à chaque push" .-> GH["GitHub leonheu/portfolio"]
U["Visiteur"] -- "https://leonheu.fr" --> TR["Traefik\n(TLS, HSTS, CrowdSec)"] --> S
Points sensibles : aucun secret côté site (statique) ; les seuls secrets
sont ceux de la CI (déjà en place : forgejo_token, token Coolify). Données
personnelles : celles que je publie, éditées comme du contenu.
Modèle de contenu (collections Astro)
Pas de base de données : des collections typées, un fichier Markdown ou JSON par entrée, validées au build (un champ manquant = build rouge, donc attrapé par la CI avant mise en ligne).
erDiagram
PROJET {
string titre
string description
string[] technologies
string url_depot "GitHub"
string url_live "site ou doc, optionnel"
int ordre "position d'affichage"
bool mis_en_avant
}
EXPERIENCE {
string intitule
string organisation
date debut
date fin "vide = en cours"
string description
}
FORMATION {
string intitule
string organisme
date debut
date fin
}
COMPETENCE {
string domaine "dev, infra-ops, outils"
string[] items
}
PROFIL {
string nom
string titre_pro
string accroche
string email "obfusqué au rendu"
string linkedin
string github
string docs "https://docs.leonheu.fr"
}
PROFIL est un singleton (un seul fichier) ; les autres collections
grossissent au fil de l'eau — ajouter un projet = ajouter un fichier, la CI
et le déploiement font le reste. La structure des collections est pensée
pour l'i18n Astro (US-06) : la version anglaise réutilisera les mêmes
schémas.
En production
- https://www.leonheu.fr (l'adresse canonique que j'ai choisie ;
leonheu.frredirige en 301) — depuis le 2026-07-19, versionv1.0.0(premier tag posé par la chaîne git-flow + Commitizen). - App Coolify
portfolio(projet Coolify « Portfolio », uuideeryluj6zvmb7gfehv3vm8mj), déployée par l'étapedeployde la CI surmain. - ⚠️ Piège appris : dans Coolify, l'URL d'un dépôt Forgejo doit porter le port
SSH dans l'adresse scp :
git@10.9.73.81:2222/leon/<repo>.git(la formessh://est refusée par l'API, et sans le port le clone tente le 22).