LADTC
Site WordPress lourd à maintenir pour un club de trail belge. Remplacé par une application Next.js auto-hébergée — blog intégré, gestion des membres, commandes d'équipement, événements, zéro CMS externe.

Problème
Le club LADTC (Ellezelles, Belgique) s'appuyait sur un site WordPress difficile à maintenir : plugins à mettre à jour, performance médiocre, contenu éditorial figé. Les besoins du comité débordaient du cadre CMS : gestion des membres, suivi des cotisations, commandes d'équipement, inscriptions aux événements, espace documents interne. Chaque fonction ajoutée via un plugin tiers multipliait les points de fragilité.
Solution
Remplacement complet par une application Next.js 16 auto-hébergée sur un homelab personnel. Blog intégré directement dans la base de données (plus de CMS externe), authentification email avec rôles, modules fonctionnels codés sur mesure. Déploiement par git push vers un serveur Coolify, exposition sécurisée via Cloudflare Tunnel sans ouvrir le moindre port.
Architecture
GitHub (push master)
│ webhook
Coolify (UM880 Pro, homelab)
├── Build Docker multi-stage
├── Entrypoint → migrations Prisma auto
└── Runner slim Next.js
│
Cloudflare Tunnel (zéro port ouvert)
│
PostgreSQL 15 (même hôte, Docker)
│
Sentry + Uptime Kuma
Le pipeline push → build → migrations → start est entièrement automatique. L'entrypoint Docker charge le CLI Prisma depuis un répertoire isolé (/prisma-cli) pour éviter les conflits avec les node_modules du runner slim.
Stack technique
| Composant | Technologie |
|---|---|
| Frontend | Next.js 16 (App Router), React 19, TypeScript 5.7 |
| UI | Tailwind CSS v4 + shadcn/ui |
| Data client | TanStack Query (staleTime + invalidation, pas de polling) |
| ORM | Prisma 7 |
| Base de données | PostgreSQL 15 (Docker) |
| Auth | BetterAuth (email/password, RBAC : MEMBER, COACH, COMMITTEE, ADMIN) |
Resend (SPF + DKIM + DMARC p=quarantine) | |
| Monitoring | Sentry (client + server, DSN public au build) + Uptime Kuma |
| Hébergement | Coolify (self-hosted Docker) |
| Reverse proxy | Cloudflare Tunnel → Traefik |
Modules livrés
- Blog : CRUD admin, rendu Markdown, intégré à la base (plus de dépendance WordPress)
- Membres : profils, statut cotisation, historique
- Commandes équipement : catalogue, panier, checkout
- Événements : création, inscriptions, suivi
- Galerie photos : administration, affichage public
- Documents internes : upload, notes associées, catégorisation
- Pages statiques : accueil, équipe, contact
- Admin : tableau de bord unifié pour le comité
Résultats
- Migrations automatiques : l'entrypoint Docker applique les migrations Prisma à chaque déploiement, sans intervention manuelle
- Email conforme : trio SPF/DKIM/DMARC configuré, passage progressif
p=none → p=quarantine, rapports agrégés vers une boîte dédiée - Monitoring opérationnel : instrumentation Sentry client + serveur, compatible Turbopack via
instrumentation-client.ts - Sécurité réseau : aucun port exposé sur la box, traversée Cloudflare Tunnel uniquement
- Zéro coût d'hébergement : tout tourne sur le homelab, seul le domaine reste payant
Ce que j'ai appris
- Construire un pipeline CI/CD self-hosted fiable (webhook GitHub → Coolify → build Docker → migrations → redémarrage)
- Embarquer un CLI Prisma dans un runner Docker slim sans casser le
node_modulesapplicatif - Contourner la spécificité Turbopack sur Next.js 16 :
sentry.client.config.tsn'est pas bundlé, il faut basculer surinstrumentation-client.ts - Configurer une authentification stricte avec rôles sans dépendre d'un service externe (BetterAuth)
- Maîtriser la chaîne email transactionnelle complète (SPF, DKIM, DMARC, Resend, OVH MX)
- Exposer une application en production sans ouvrir de port grâce à Cloudflare Tunnel