Portfolio mprost.fr — Conception, Sécurisation et Auto-hébergement d'un site Next.js
Conception, sécurisation et auto-hébergement de mon portfolio professionnel avec Next.js, MDX, Proxmox, Nginx et Node.js. Le projet intègre un déploiement automatisé avec GitHub Actions ainsi qu'un formulaire sécurisé relié à une messagerie Stalwart auto-hébergée.
Portfolio mprost.fr
Introduction
mprost.fr est mon portfolio professionnel. Il centralise ma présentation, mon parcours, mon CV, mes projets ainsi que mes documentations techniques.
J'ai développé et fait évoluer ce projet afin de maîtriser l'ensemble de la chaîne technique d'un service Web : développement de l'application, gestion du contenu, sécurisation, versionnement, déploiement, hébergement, exposition sur Internet et messagerie associée.
Le site repose sur Next.js et utilise principalement des contenus générés statiquement. Certaines fonctionnalités nécessitent néanmoins une exécution côté serveur, notamment le formulaire de contact.
Le projet était auparavant hébergé sur Plesk. Il a ensuite été migré vers ma propre infrastructure Proxmox, avec un conteneur Debian dédié au Web, Nginx comme reverse proxy, un déploiement automatisé depuis GitHub et une messagerie Stalwart hébergée sur une VM séparée.
Objectifs
- Présenter mon profil, mon CV, mes réalisations et mes documentations dans un site unique.
- Publier facilement de nouveaux projets et documentations grâce à MDX.
- Héberger l'application sur ma propre infrastructure.
- Séparer les rôles Web et messagerie dans des environnements distincts.
- Protéger le formulaire de contact contre les robots, le spam et les abus.
- Acheminer les messages du formulaire directement vers ma messagerie auto-hébergée.
- Conserver les secrets uniquement côté serveur.
- Versionner le code avec Git et automatiser la mise en production.
- Journaliser les événements utiles à la sécurité et au diagnostic.
- Limiter la collecte de données personnelles et documenter leur traitement.
- Suivre le référencement et la qualité du site.
Stack technique
| Domaine | Technologies | Rôle |
|---|---|---|
| Framework | Next.js 16, React 19, TypeScript | Pages, routage, rendu serveur et routes API |
| Interface | Tailwind CSS, Tailwind Typography, Framer Motion, Lucide | Design, mise en page, animations et icônes |
| Thème | next-themes | Mode clair et sombre |
| Contenu | MDX, next-mdx-remote, gray-matter | Projets et documentations avec métadonnées |
| Veille | rss-parser | Exploitation de flux RSS |
| Anti-robot | Cloudflare Turnstile | Protection du formulaire de contact |
| Envoi du formulaire | Nodemailer, SMTP TLS | Transmission directe du message vers la messagerie |
| Messagerie | Stalwart Mail Server | Boîte contact@mprost.fr, SMTP et IMAP |
| Hyperviseur | Proxmox VE | Hébergement des services |
| Serveur Web | LXC Debian 13 | Isolation de l'application Web |
| Serveur Mail | VM Debian 13 | Isolation de la messagerie |
| Reverse proxy | Nginx | Entrée HTTP/HTTPS et transmission vers Next.js / WebUI mail |
| Runtime | Node.js | Exécution de Next.js en production |
| Gestion du service | systemd | Démarrage et maintien du processus Next.js |
| Versionnement | Git / GitHub | Historique et dépôt du code source |
| Déploiement | GitHub Actions, runner self-hosted | Déploiement automatique du portfolio |
| DNS | IONOS | Gestion du domaine et des enregistrements Web/Mail |
Architecture générale
Le portfolio et la messagerie sont hébergés sur la même infrastructure Proxmox, mais dans deux environnements distincts.
Internet
|
mprost.fr
|
DNS IONOS
|
IP publique
|
Routeur / NAT
|
+--------------+--------------+
| |
HTTP / HTTPS Ports mail
| |
v v
CT Web Debian 13 VM Mail Debian 13
192.168.1.210 192.168.1.211
| |
Nginx Stalwart
| SMTP / IMAP / Mail
Next.js |
| contact@mprost.fr
Portfolio
Le serveur physique exécute Proxmox VE. Le site Web fonctionne dans un conteneur LXC Debian 13 tandis que la messagerie fonctionne dans une VM Debian 13 dédiée.
Cette séparation évite de mélanger le rôle applicatif du portfolio et le rôle critique de serveur de messagerie.
Serveur Web et reverse proxy
Le conteneur Web utilise l'adresse locale :
192.168.1.210
Nginx constitue le frontal HTTP/HTTPS. Il reçoit les requêtes publiques destinées à mprost.fr et les transmet au processus Next.js exécuté localement par Node.js.
Visiteur
|
v
Nginx : 80 / 443
|
v
Next.js : 3000
|
v
Portfolio / API
Nginx sert également de reverse proxy pour l'interface Web de la messagerie accessible via mail.mprost.fr, tandis que les protocoles SMTP et IMAP sont dirigés directement vers la VM Mail.
Messagerie auto-hébergée
La messagerie @mprost.fr repose sur Stalwart Mail Server installé sur une VM Debian 13 dédiée.
La VM Mail utilise :
192.168.1.211
Le serveur expose notamment les services nécessaires à la réception, à l'envoi et à la consultation des mails. La boîte utilisée par le portfolio est :
contact@mprost.fr
Le domaine utilise des enregistrements DNS dédiés à la messagerie :
- MX pour désigner
mail.mprost.frcomme serveur de réception ; - SPF pour déclarer les serveurs autorisés à envoyer ;
- DKIM avec signatures RSA et Ed25519 ;
- DMARC pour définir la politique d'authentification ;
- enregistrements de découverte pour les clients mail.
Le serveur Web et le serveur Mail partagent le même domaine public mais conservent des rôles réseau séparés.
Organisation de l'application
L'application utilise l'App Router de Next.js.
app/
components/
content/
lib/
public/
.github/
workflows/
appcontient les pages et routes serveur ;componentscontient les composants React réutilisables ;contentcontient les contenus MDX ;libregroupe les fonctions utilitaires ;publiccontient les ressources publiques ;.github/workflowscontient le workflow de déploiement.
Le portfolio propose notamment l'accueil, la présentation, le parcours, les compétences, les projets, les documentations techniques, la veille, le CV, le formulaire de contact, les mentions légales et la politique de confidentialité.
MDX et gestion du contenu
Une partie importante du portfolio repose sur MDX.
Chaque projet ou documentation peut être représenté par un fichier comportant ses propres métadonnées : titre, description, date, tags ou lien de démonstration.
Code Next.js
+
Contenu MDX
=
Portfolio
Cette organisation permet d'ajouter de nouvelles publications sans créer manuellement une page React complète pour chaque contenu.
Formulaire de contact
Le formulaire de contact est la principale fonctionnalité dynamique du portfolio.
L'ancienne architecture utilisait Formspree comme relais. Cette dépendance a été supprimée. La route serveur du portfolio envoie maintenant directement les messages vers Stalwart avec Nodemailer et une connexion SMTP chiffrée.
Le parcours est désormais :
Visiteur
|
Formulaire mprost.fr
|
/api/contact
|
Contrôle Origin
|
Rate limiting
|
Validation des champs
|
Honeypot
|
Cloudflare Turnstile
|
Nodemailer
|
SMTP TLS :465
|
Stalwart
|
contact@mprost.fr
L'adresse saisie par le visiteur est utilisée comme Reply-To, tandis que l'expéditeur SMTP reste la boîte du domaine. Cela permet de répondre au visiteur depuis la messagerie sans faire passer son adresse pour l'expéditeur technique du message.
Sécurité applicative
Cloudflare Turnstile
Le widget Turnstile fournit un jeton côté navigateur. La route /api/contact vérifie ensuite ce jeton côté serveur avec la clé secrète Turnstile.
La clé de site reste publique dans le composant client. La clé secrète n'est jamais incluse dans le dépôt Git.
Limitation de débit
Deux niveaux sont appliqués :
- limite par adresse IP ;
- plafond global du formulaire.
Ces limites réduisent les envois répétés et l'utilisation abusive de la route serveur.
Honeypot
Un champ invisible pour un visiteur normal permet de détecter certains robots remplissant automatiquement tous les champs d'un formulaire.
Contrôle d'origine
La route vérifie l'en-tête Origin pour accepter uniquement les domaines prévus par l'application.
Validation côté serveur
Le nom, l'adresse email, le message et le jeton Turnstile disposent de contrôles de présence, de format et de taille.
Gestion des secrets
Les secrets de production ne sont pas stockés dans GitHub. Ils sont placés sur le serveur dans un fichier d'environnement dédié chargé par systemd.
Les variables comprennent notamment :
TURNSTILE_SECRET_KEY
SMTP_HOST
SMTP_PORT
SMTP_SECURE
SMTP_USER
SMTP_PASSWORD
CONTACT_TO
Le fichier de production reste séparé du dépôt. Un fichier .env.example peut documenter les variables nécessaires sans contenir leurs valeurs.
Journalisation et détection
La route /api/contact journalise les événements importants afin de faciliter la détection des abus et le diagnostic.
Les événements peuvent notamment représenter :
- un message envoyé avec succès ;
- une limitation de débit ;
- un CAPTCHA absent ou refusé ;
- le déclenchement du honeypot ;
- une origine incorrecte ;
- des données invalides ;
- une erreur de configuration ;
- une erreur SMTP.
Les journaux ne contiennent pas le nom, l'adresse email ou le contenu du message. Les journaux de sécurité sont conservés séparément des ressources publiques du site.
HTTPS et TLS
Les accès Web publics utilisent HTTPS.
Navigateur
|
| HTTPS
v
Nginx
|
| HTTP local
v
Next.js
mail.mprost.fr utilise également Nginx comme frontal HTTPS pour l'interface Web de Stalwart.
Les protocoles mail TLS, comme SMTP Submission et IMAP, aboutissent directement sur Stalwart. Le certificat Let's Encrypt utilisé par Nginx a donc également été importé dans Stalwart afin d'éviter l'utilisation du certificat auto-signé sur les connexions directes aux services mail.
Versionnement avec Git
Le code source du portfolio est versionné avec Git et hébergé dans un dépôt GitHub.
Poste de développement
|
| commit / push
v
GitHub
|
v
GitHub Actions
|
v
Serveur de production
Les secrets de production ne transitent pas dans ce dépôt.
Déploiement automatisé avec GitHub Actions
Le workflow de déploiement est stocké dans :
.github/workflows/deploy.yml
Il est déclenché lors d'un push sur la branche principale.
Le workflow est exécuté par un runner GitHub Actions auto-hébergé installé sur le conteneur Web.
Runner : mprost-production
Compte : github-runner
Le cycle est :
Modification locale
|
git add
|
git commit
|
git push
|
GitHub
|
GitHub Actions
|
Runner mprost-production
|
+--> git pull
+--> npm ci
+--> npm run build
+--> restart mprost.service
|
v
Production
Sécurisation du runner
Le runner fonctionne avec le compte Linux dédié github-runner et non avec root.
Une Deploy Key SSH dédiée lui permet de récupérer le dépôt privé. Le serveur de production utilise uniquement l'accès nécessaire au déploiement.
La règle sudo du runner est limitée au redémarrage de mprost.service, conformément au principe du moindre privilège.
Exécution de Next.js avec systemd
L'application Next.js est exécutée comme un service systemd :
mprost.service
systemd permet au site de fonctionner indépendamment d'une session SSH et de redémarrer proprement après un déploiement.
Le service charge également le fichier d'environnement de production contenant les secrets nécessaires à la route de contact.
Séparation des responsabilités
IONOS
└── Domaine et DNS
Routeur
├── HTTP / HTTPS vers Nginx
└── SMTP / IMAP vers Stalwart
Proxmox VE
├── CT Web Debian 13
│ ├── Nginx
│ ├── Node.js / Next.js
│ ├── systemd
│ └── GitHub Actions Runner
│
└── VM Mail Debian 13
└── Stalwart Mail Server
GitHub
└── Dépôt source
GitHub Actions
└── Orchestration du déploiement
MDX
└── Contenu du portfolio
Cette séparation simplifie le diagnostic et évite de concentrer les rôles Web, déploiement et messagerie dans un seul service.
Conformité et protection des données
Le formulaire collecte uniquement les informations nécessaires à la réponse : nom, adresse email et message.
Le traitement ne repose plus sur Formspree. Après validation des contrôles de sécurité, les messages sont envoyés directement vers la boîte contact@mprost.fr de l'infrastructure de messagerie auto-hébergée.
Cloudflare Turnstile reste utilisé comme service externe de protection anti-robot.
Le journal de sécurité reste séparé du contenu des messages et ne journalise pas le nom, l'adresse email ou le texte envoyé.
Le site dispose de pages dédiées aux mentions légales et à la politique de confidentialité.
Référencement et qualité
Le portfolio intègre notamment :
- des métadonnées par page ;
- un sitemap ;
- un fichier robots.txt ;
- la génération statique lorsque cela est pertinent ;
- Google Search Console ;
- Lighthouse.


Évolution du projet
Hébergement initial sous Plesk
Les premières versions en production étaient hébergées sous Plesk avec un environnement Node.js administré par la plateforme.
Passage à l'auto-hébergement
Le portfolio a ensuite été migré sur Proxmox :
Serveur physique
|
Proxmox VE
|
CT Debian 13
|
+-- Nginx
+-- Node.js / Next.js
+-- systemd
+-- GitHub Actions Runner
Passage au déploiement continu
Le déploiement manuel a été remplacé par un workflow GitHub Actions exécuté directement sur l'infrastructure grâce à un runner self-hosted.
Auto-hébergement de la messagerie
Une VM Debian 13 dédiée a ensuite été ajoutée pour héberger Stalwart Mail Server.
Le domaine mprost.fr utilise maintenant mail.mprost.fr pour sa messagerie, avec une boîte contact@mprost.fr et les mécanismes DNS d'authentification associés.
Suppression de Formspree
Le formulaire dépendait initialement de Formspree pour acheminer les messages. Cette dépendance a été supprimée.
La route serveur Next.js utilise désormais Nodemailer pour établir une connexion SMTP TLS authentifiée avec Stalwart et remettre directement les messages dans contact@mprost.fr.
Difficultés rencontrées
Application Next.js derrière Nginx
Le portfolio n'est pas un simple ensemble de fichiers HTML. Les routes API nécessitent un processus Node.js actif. Nginx agit donc comme reverse proxy vers Next.js.
Ressources du runner GitHub Actions
La configuration initiale du conteneur Web disposait de trop peu de mémoire pour certains npm ci et builds. Un job a été interrompu par le mécanisme OOM du système. Les ressources du conteneur ont ensuite été augmentées.
Permissions Git du runner
Le runner utilise un compte Linux différent du propriétaire historique du dépôt. Il a fallu gérer proprement les permissions et déclarer le dépôt utilisable par le compte de déploiement.
Authentification SSH GitHub
Le runner dispose de sa propre Deploy Key SSH en lecture seule afin de récupérer le dépôt privé sans réutiliser une identité personnelle.
Reverse proxy vers Stalwart
L'interface Web Stalwart est publiée via Nginx sous mail.mprost.fr, avec une URL publique cohérente pour OAuth et JMAP.
Certificat TLS des protocoles mail
Le certificat Let's Encrypt du frontal Web ne couvre pas automatiquement les connexions directes SMTP/IMAP vers Stalwart. Le certificat valide de mail.mprost.fr a donc été importé dans Stalwart pour remplacer le certificat auto-signé présenté initialement sur les services mail.
Migration du formulaire hors Formspree
Le remplacement de Formspree a nécessité :
- l'installation de Nodemailer ;
- l'ajout des variables SMTP côté serveur ;
- la configuration du certificat TLS Stalwart ;
- la configuration d'une authentification SMTP pour
contact@mprost.fr; - l'adaptation des mentions RGPD et de la politique de confidentialité.
Compétences mobilisées
Développement Web
- Next.js ;
- React ;
- TypeScript ;
- Tailwind CSS ;
- MDX ;
- routes serveur ;
- Nodemailer ;
- génération statique et dynamique.
Système et hébergement
- Debian 13 ;
- Node.js ;
- systemd ;
- Nginx ;
- exploitation de services en production.
Virtualisation
- Proxmox VE ;
- conteneurs LXC ;
- machines virtuelles ;
- séparation des rôles applicatifs.
Réseau
- adressage IPv4 ;
- DNS ;
- NAT/PAT ;
- HTTP / HTTPS ;
- SMTP / IMAP ;
- reverse proxy ;
- TLS.
Messagerie
- Stalwart Mail Server ;
- SMTP Submission ;
- IMAP ;
- MX ;
- SPF ;
- DKIM ;
- DMARC ;
- certificats TLS.
DevOps et versionnement
- Git ;
- GitHub ;
- GitHub Actions ;
- runner self-hosted ;
- pipeline de build et de déploiement ;
- Deploy Keys SSH.
Sécurité
- principe du moindre privilège ;
- séparation des comptes système ;
- clés SSH ;
- HTTPS et SMTP TLS ;
- gestion de secrets hors Git ;
- Cloudflare Turnstile ;
- rate limiting ;
- validation des entrées ;
- honeypot ;
- journalisation.
Protection des données
- minimisation des données ;
- politique de confidentialité ;
- suppression d'un relais tiers du chemin des messages ;
- séparation des journaux techniques et du contenu des messages ;
- conservation limitée des journaux.
SEO et qualité Web
- métadonnées ;
- sitemap ;
- robots.txt ;
- Google Search Console ;
- Lighthouse.
Pistes d'amélioration
Déploiement sans interruption
Construire les nouvelles versions dans un emplacement séparé, effectuer un contrôle de santé puis basculer vers la nouvelle release seulement si le build est valide.
Synchronisation des certificats
Automatiser la synchronisation du certificat Let's Encrypt de mail.mprost.fr vers Stalwart après chaque renouvellement afin que SMTP et IMAP présentent toujours un certificat valide.
Sécurité HTTP
Renforcer progressivement les en-têtes HTTP, notamment CSP, HSTS et X-Content-Type-Options, en conservant la compatibilité avec Cloudflare Turnstile.
Journalisation et supervision
Centraliser les événements Nginx, Next.js, systemd et Stalwart afin de faciliter la supervision et la création d'alertes.
Sauvegarde et restauration
Formaliser une stratégie couvrant :
- le conteneur Web ;
- la VM Mail ;
- les données de messagerie ;
- les configurations Nginx et Stalwart ;
- les variables d'environnement ;
- les certificats ;
- les journaux utiles ;
- la procédure de restauration.
Conclusion
Le portfolio mprost.fr a progressivement évolué d'un site personnel vers un projet complet associant développement Web, cybersécurité, Linux, réseau, virtualisation, DevOps et messagerie.
Next.js et MDX constituent la base applicative et éditoriale. Proxmox héberge les différents services. Nginx assure l'entrée Web, systemd maintient l'application, GitHub Actions automatise les déploiements et Stalwart fournit désormais la messagerie du domaine.
Le formulaire de contact ne dépend plus d'un relais Formspree : après ses contrôles de sécurité, la route serveur transmet directement les messages via SMTP TLS à la messagerie auto-hébergée.
Développement
|
Git / GitHub
|
GitHub Actions
|
Runner de production
|
Next.js / Nginx
|
Formulaire sécurisé
|
Nodemailer / SMTP TLS
|
Stalwart
|
contact@mprost.fr
Ce projet constitue désormais un environnement concret pour mettre en pratique le développement, l'exploitation système, la sécurité, le réseau, la messagerie et l'automatisation autour d'un service réellement accessible sur Internet.