Comment créer un SaaS nextjs + mongoDB entièrement auto-hébergé
Je voulais construire un SaaS permettant aux utilisateurs de visualiser, éditer et partager facilement des fichiers docker-compose. Si vous ne connaissez rien à Docker, ce n'est pas grave. Cet article est centré sur la stack technologique du SaaS.
Mes besoins étaient les suivants :
- Un système utilisateur
- Des analyses
- Un système de blog
- Un système de documentation
- Une base de données me permettant de tester rapidement de nouvelles choses
- La stack technologique doit être facilement auto-hébergeable
Choisir une base de données
Le choix de la base de données est délicat. Dois-je opter pour SQL ou NoSQL ?
À mon avis, nous devrions choisir une base de données qui s'adapte à la forme de nos données, et non modifier nos données pour les faire rentrer dans la base de données. Et si vous connaissez un peu les docker-composes, c'est une structure de données très complexe à stocker, car assez incohérente (je veux dire, même si c'est basé sur YAML, il existe tellement de possibilités différentes). Le stocker dans une base de données SQL serait un cauchemar, la seule "solution facile" serait de le considérer comme du texte brut et de le stocker dans une cellule texte (ou octets, peu importe).
Oui, je pourrais utiliser la cellule JSON de PostgreSQL pour créer un moyen de le stocker commodément, mais rappelez-vous de notre besoin : garder les choses simples
.
J'ai donc choisi NoSQL pour sa capacité à stocker des données non structurées.
Mais quelle base de données NoSQL ?
Choisir une base de données NoSQL n'est que la moitié du chemin pour choisir une base de données. Il reste encore tellement de questions à se poser.
Mais rappelez-vous toujours ceci quand vous êtes une petite équipe ou un développeur solo : garder les choses simples
.
Je vais donc me concentrer sur ces questions :
- Existe-t-il un driver TypeScript facile à utiliser ?
- La base de données est-elle sécurisée ?
- Puis-je l'auto-héberger ?
- Y a-t-il une grande communauté ?
J'ai pensé à SurrealDB et MongoDB. Ils ont tous deux un SDK TS, n'ont pas de nouvelles CVE chaque matin, et sont entièrement auto-hébergeables.
SurrealDB
SurrealDB pourrait être une très bonne option, car il peut être utilisé comme une base de données SQL pour ma partie utilisateur et NoSQL pour mon traitement de données et mes tâches.
Mais le grand inconvénient est le manque de maturité. Même si les développeurs sont rapides pour répondre aux problèmes soumis, il n'y a pas beaucoup de ressources sur Stack Overflow ou d'autres espaces de connaissances à son sujet.
Le choix final : MongoDB
J'ai finalement choisi MongoDB car il me permettrait de modifier rapidement le modèle de données de mes entités, et il existe une documentation et des connaissances beaucoup plus importantes à son sujet.
À ce stade, je savais que j'utiliserais NextJS + MongoDB, mais qu'en est-il du système de blog, de la documentation et des analyses ?
La partie auto-hébergement
Avant d'aller plus loin, j'ai commencé ma première version bêta avec très peu d'utilisateurs. J'avais donc besoin d'auto-héberger la stack. Mes deux plus grandes préoccupations étaient : je veux que ce soit peu coûteux et facile.
J'ai choisi hetzner.com car ils sont vraiment peu coûteux et fiables. 4,51 € /mois pour 2 CPU, 4 Go de RAM, 20 To de bande passante et 40 Go de SSD. Pour gérer mon serveur privé virtuel, j'ai choisi Coolify, car c'est entièrement open-source et me permet de déployer facilement de nouveaux services.
Les analyses, le blog et la documentation :
Le choix des analyses était très simple pour moi car j'utilise Umami Analytics depuis 2020. C'est entièrement auto-hébergé, open source et conforme au RGPD.
Mes besoins en matière de blog étaient un peu particuliers car je voulais quelque chose de headless avec une interface d'administration et auto-hébergeable. J'aurais pu opter pour Strapi, mais j'ai finalement choisi Directus sans raison particulière, les deux pouvant parfaitement convenir à mon cas d'utilisation.
Concernant la documentation, mon choix a été guidé par : peu coûteux et rapide
. J'aurais donc pu choisir n'importe quelle solution de documentation basée sur Markdown. Voici quelques bons choix :
- Docusaurus
- Hugo
- mkDocs
- markdoc
J'ai opté pour Docusaurus car il est basé sur React, et à l'avenir, si nécessaire, je pourrais facilement ajouter des composants personnalisés.
N'y a-t-il pas de problèmes de référencement en utilisant différentes technologies pour la documentation et le blog ?
Pour éviter les problèmes de référencement associés aux sites web multi-domaines comme composecraft.com
, docs.composecraft.com
, blog.composecraft.com
.
J'ai opté pour une approche différente :
Premièrement, mon système de blog est plus un système de bibliothèque. Directus m'aide uniquement à gérer les entrées, mes données contiennent un champ markdown qui alimente directement mon NextJS, donc pour la partie blog (ou bibliothèque comme vous voulez), tout est sous composecraft.com/library et NextJS le gère avec la bibliothèque next-remote-mdx.
Bien que j'aurais pu utiliser le même modèle pour ma documentation, j'ai choisi Docusaurus. Pourquoi ? Parce que ma documentation va rapidement évoluer, et je ne veux pas me soucier des questions NextJS lors de la rédaction. Je veux simplement écrire des fichiers markdown sans me préoccuper de la réactivité mobile, des performances ou autre. Utiliser Docusaurus impose automatiquement à ma documentation d'être structurée, facile à éditer et facile à utiliser par mes utilisateurs.
J'ai donc simplement configuré mon proxy inverse pour rediriger toute requête sous /doc vers le Docker Docusaurus géré par Coolify.
Le proxy inverse :
À mon avis, surtout pour choisir un proxy inverse pour un site web de faible à moyenne charge, choisissez celui que vous aimez. Il n'y a pas de choix "informatique" meilleur entre nginx, traefik, apache ou caddy tant que vous restez sur un serveur simple sans équilibrage de charge ou routage complexe.
Les sauvegardes ?
Comment m'assurer que ma base de données auto-hébergée ne disparaisse pas quand mon serveur va brûler à cause de mes trop nombreux utilisateurs ?
Jusqu'à présent, mon serveur est loin de brûler à cause de mes trop nombreux utilisateurs, mais quoi qu'il en soit, j'ai intégré un mécanisme de sauvegarde. Lequel ? Chaque jour à 3h du matin, une sauvegarde complète de la base de données est programmée et stockée sur un S3 distant chez un fournisseur cloud (différent de mon fournisseur de serveur privé virtuel pour éviter qu'ils ne placent le compartiment S3 dans le même centre de données que mon serveur de production).
Dernière préoccupation : le CDN
En tant que petit produit utilisé dans le monde entier, j'ai été confronté à un problème : mes utilisateurs américains se plaignaient de la latence, et en effet, le serveur est situé en Europe.
Réponse facile : je pourrais avoir une instance aux États-Unis !
Mais... rappelez-vous que c'est un petit projet et je veux que ce soit peu coûteux et facile
. J'ai donc choisi de faire appel à Cloudflare avec leur CDN gratuit. Oui, ce n'est pas une stack entièrement auto-hébergée respectueuse de la confidentialité. Mais pour une petite équipe de produit, c'est le meilleur compromis coût/performance que je pouvais faire.
Le schéma final :
Quelques réflexions
Aurais-je pu le construire plus simplement ?
Oui, définitivement : si mon client final était totalement non technique, j'aurais travaillé davantage sur la documentation et réutilisé directement Directus pour gérer ma documentation en même temps que mes bibliothèques. Et si le client ne veut absolument pas interagir avec un serveur Linux : utiliser MongoDB Atlas et des solutions cloud pour les analyses, et quelque chose comme Vercel, Netlify ou fly.io pour déployer mon application NextJS sans état.
Mais comme je suis un amateur de Linux et que je n'ai pas peur de mettre la main à la pâte, je pense que c'est la stack la plus économique et la plus facilement maintenable qui me convienne.
Envie d'aller plus loin ?
Je vais bientôt créer des articles sur le pipeline CI/CD et un autre sur la logique interne de NextJS. Restez informé des nouveaux articles en vous abonnant à la newsletter ci-dessous :