Contexte
Mon ancien site, en PHP, n'était plus maintenu. Je voulais le remplacer par un site qui remplisse quatre exigences :
- lisible en cinq secondes par un recruteur : nom, rôle, expériences et contact visibles sans défiler ;
- éditable sans compétence technique : modifier un texte ne doit demander ni compilation ni base de données ;
- hébergeable partout : un hébergement mutualisé classique (Apache + PHP) doit suffire ;
- sécurisé par défaut, puisque c'est mon métier.
Architecture
flowchart LR
subgraph edit["Édition"]
md["Fichiers Markdown<br/>content/fr · content/en"]
end
subgraph tools["Outils locaux (Node)"]
gen["tools/"] --> og["Images de partage"]
gen --> qr["QR code"]
end
subgraph host["Hébergement mutualisé : Apache + PHP"]
pages["Pages statiques<br/>/ · /cv · /projets · /blog"]
api["api/contact.php"]
end
md --> pages
md --> gen
visitor(("Visiteur")) -->|"HTTPS + CSP stricte"| pages
visitor -->|"jeton signé"| api
api --> mailbox[("Boîte mail")]Un petit script transforme le contenu Markdown en pages HTML complètes, lisibles par les moteurs de recherche et les robots des IA sans exécuter de JavaScript. Dans le navigateur, le même code de rendu reprend la main pour les animations et l'interactivité. Publier un texte, c'est modifier un fichier .md, lancer le script, puis pousser : le déploiement est automatique.
Choix techniques
| Besoin | Choix | Pourquoi |
|---|---|---|
| Contenu éditable | Markdown + parseur maison | Ni CMS, ni base de données, ni compilation |
| Interface | HTML, CSS et JavaScript natifs | Zéro dépendance, rapide, durable |
| Hébergement | Mutualisé Apache + PHP | Coût minimal ; .htaccess pour le cache et la sécurité |
| Formulaire | PHP sans dépendance | Jeton signé, limitation de débit, adresse jamais exposée |
| Schémas | Mermaid auto-hébergé | Chargé uniquement sur les pages qui en contiennent |
| Aperçus, QR | Scripts Node locaux | Toujours alignés avec le contenu, rien à publier en plus |
Sécurité
- Politique de contenu stricte (
script-src 'self') : aucun script inline, aucune ressource tierce, police auto-hébergée. - En-têtes HSTS,
X-Frame-Options,Permissions-Policy, isolationCross-Origin-*. - Rendu du Markdown sans
innerHTML: le HTML éventuellement présent dans le contenu n'est jamais interprété. - Formulaire de contact : jeton HMAC à usage unique, contrôle d'origine, champ piège, limitation par IP hachée, en-têtes de mail non injectables. L'adresse de destination n'existe que dans la configuration serveur.
Résultats
- 0 dépendance de production, 0 requête vers un tiers ;
- mise à jour du contenu = modifier un fichier texte.