Aller au contenu

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.fr redirige en 301) — depuis le 2026-07-19, version v1.0.0 (premier tag posé par la chaîne git-flow + Commitizen).
  • App Coolify portfolio (projet Coolify « Portfolio », uuid eeryluj6zvmb7gfehv3vm8mj), déployée par l'étape deploy de la CI sur main.
  • ⚠️ 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 forme ssh:// est refusée par l'API, et sans le port le clone tente le 22).