(3/3) - Comment créer un produit : Guide étape par étape
Publié le - 8 février 2025 par Andy Cinquin
VPSCoolifyCloudflareTutoEntrepreneurPocketBase
Guide complet pour créer un produit avec succès - Partie 3
Cet article suppose que vous avez lu les deux premiers articles de la série :
- FR :
- EN :
Vous devriez donc avoir une idée précise de ce que vous voulez, une validation de votre produit, une maquette relativement avancée, et une idée de comment réaliser tout cela.
Faisons une pause, respirons un peu, et je vais vous donner un exemple concret sur les choix que j'ai faits jusqu'ici, ce que j'ai installé, et nous allons rentrer un peu dans le détail.
Récapitulatif !
- On trouve une idée ✅
- On en parle, on la valide ✅
- On définit un MVP (Minimum Viable Product), en gros la version la plus petite possible qui répond au besoin ✅
- On réalise ce MVP ✅
- Design simple ✅
- Fonctionnalités simples ✅
- Hébergement simple ✅
- On le fait tester
- On continue à l'améliorer
- On fait la communication autour
- Et voilà !
On trouve une idée
Dans mon cas, le besoin vient de moi, mais j'aurais très bien pu récupérer l'idée d'un proche ! Je vais prendre ForVoyez comme exemple : un SaaS qui permet de traduire les images sous forme de textes pour une question d'accessibilité et de référencement !
On en parle
J'utilise plusieurs outils pour maquetter et prototyper quelque chose qui me convient et qui me plaît :
- Figma: The Collaborative Interface Design Tool (optionnel)
- Excalidraw | Hand-drawn look & feel • Collaborative • Secure (optionnel)
- v0 by Vercel (optionnel)
- Claude (ou ChatGPT)
Une fois le brainstorming effectué avec mon associé, nous trouvons une idée de nom, créons le logo et établissons la charte graphique. Pour trouver des inspirations, nous utilisons :
- Refero — UI/UX Design Inspiration for Your Next Project (optionnel)
- Dribbble - Discover the World's Top Designers & Creative Professionals
Pour les couleurs, nous partons de celles que nous aimons bien quand nous générons notre logo avec :
- Midjourney (ou Bing Image Generator, ChatGPT, etc.)
Nous nous basons sur les concepts de design qui viennent de TailwindCSS :
- Refactoring UI avec leur super livre (optionnel)
Pour les couleurs, à partir du logo, nous adaptons une palette avec ce type d'outils :
- Tailwind CSS Color Generator | UI Colors (optionnel)
Pour les typographies, nous choisissons quelque chose qui nous plaît sur Google Fonts :
- Browse Fonts - Google Fonts (optionnel)
Pour les icônes, nous pouvons utiliser :
- Font Awesome (optionnel)
- Lucide (optionnel)
Avec tous ces éléments, cela permet d'aller plus vite pour faire une maquette propre. On peut aussi se passer de tout cela et faire tout à la main, encore une fois, cela dépend de chacun.
On fait le choix de nos technologies
Première possibilité : peu de logique et web app en SaaS
Ici, nous ne nous prenons pas la tête. Pas énormément de charge à prévoir, surtout au début, donc nous faisons petit et rapide. Le choix se porte donc vers "Clerk" qui permet de gérer l'intégralité de l'authentification.
Nous n'avons pas besoin de beaucoup de logique, c'est juste un endpoint avec de la logique à l'intérieur, tout le travail se fait via les API d'OpenAI. Donc nous partons au plus "simple" pour nous :
Nous utilisons une base de données PostgreSQL car nous avons l'habitude de travailler avec. (En mode développement, j'utilise Neon pour éviter d'installer PostgreSQL en local sur ma machine, cela me permet également d'utiliser la même base de données entre mon PC portable et mon PC fixe)
- Neon Serverless Postgres — Ship faster (à ne pas utiliser en production car très cher)
L'intégralité de l'application est développée en back + front avec NextJS (car Next permet de gérer du backend également).
Nous gérons nos appels en base de données avec Prisma (un ORM) :
Cela nous permet de tout gérer directement en local pour le moment, nous ne nous préoccupons pas du déploiement à ce stade.
Tout est sur GitHub (GitHub), en public, car nous aimons l'open source et nous y croyons !
Nous développons ensuite la première version de notre application : la logique, une base de front-end, l'authentification, etc. L'entièreté du SaaS en un petit week-end !
Toute la logique de paiement, tokens, etc., est gérée via des webhooks et avec une connexion avec :
(En réalité, nous aurions dû utiliser Stripe, qui est beaucoup plus efficace).
Deuxième possibilité : besoin de découpler l'API du front à 100%
Pour de nombreuses raisons, nous pourrions vouloir découpler le backend du front, et ne pas faire notre backend directement avec Next, notamment si nous devons gérer beaucoup de tables et d'endpoints, gérer beaucoup de données différentes et que nous avons plus d'un seul schéma à gérer, avec des jointures et des relations plus complexes.
Dans ce cas, nous partons sur Next, mais nous ne faisons pas de gestion de base de données via notre backend côté API NextJS, uniquement des appels vers un serveur externe.
Pour ce faire, nous utilisons :
- Next.js by Vercel - The React Framework
- Stripe | Financial Infrastructure to Grow Your Revenue
- GitHub
Même base que précédemment, mais en plus de cela, nous gérons notre backend complet avec PocketBase par exemple :
que nous faisons tourner en local pour nos tests, et que nous déploierons sur un VPS ensuite.
Nous faisons donc une V1 comme cela pour pouvoir développer tranquillement notre application.
Déploiement
Une fois notre application terminée, et que nous avons un bon début de MVP, quelque chose d'utilisable et de sympa, nous allons vouloir la déployer et la mettre en production.
C'est ici que je vais vous expliquer comment nous avons fait et l'architecture que nous utilisons.
Voici ce que j'ai aujourd'hui pour ce genre de projets :
- Un VPS chez Netcup à 6€/mois
- Un nom de domaine chez OVH que j'ai transféré chez Cloudflare à 5€/an
Et tout un tas de services gratuits à côté, nous y reviendrons.
- Coût total : 6.25€/mois MAXIMUM 😊
(C'est raisonnable pour un service qui peut prendre plusieurs centaines de milliers de visites par minute !)
Comment faire ?
Petit article d'installation d'un nouveau serveur avec Coolify :
- Installation et configuration d'un VPS pour Coolify (FR)
- VPS installation and configuration guide for Coolify (EN)
Une fois que vous avez Coolify et votre VPS configuré, vous pouvez simplement faire un lien vers votre GitHub, configurer ce qu'il vous plaît, cliquer sur "déployer", et voilà !
Exemple pour PocketBase :

On va dans nos projets, puis "new"

On sélectionne un lien GitHub ou une image existante, ici nous voulons un PocketBase :


On sélectionne PocketBase, puis le serveur de notre choix (on peut en avoir plusieurs pour qu'ils se partagent la charge)

On sélectionne ce que l'on veut et on met les noms dont on a besoin :


Puis on clique sur "déployer"

Le déploiement commence, c'est assez rapide !
On attend que le déploiement soit terminé, puis on va directement sur l'adresse que Coolify nous a donnée, ou celle qu'on a configurée, depuis le web directement.
Pour PocketBase, nous allons donc accéder, dans mon cas, à :
https://pocketbase-q4kcocww8s04owowoo0g0gws.andy-cinquin.fr/_/#/pbinstal/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJwYmNfMzE0MjYzNTgyMyIsImV4cCI6MTczOTA1MTczMiwiaWQiOiIwZ24zM2d6NmR4dDl4dzIiLCJyZWZyZXNoYWJsZSI6ZmFsc2UsInR5cGUiOiJhdXRoIn0.hRRH2ulSg6HeGWncpZucSJjIXoniK1rXeOgzR-FrKoQ
On récupère ce lien sécurisé depuis le build :


On a cette base de lien, et le token est donné dans le build qu'on retrouve dans "logs"


On copie ce token et on y accède sur le web directement :


Cela se présente comme ceci :


On a besoin d'une liste de produits ?
Pas de souci, on crée une collection "produit"


On crée la collection, la table, directement avec les noms et champs dont nous avons besoin


Il suffit ensuite de créer de nouveaux éléments, des données dans cette table.

Très bien tout cela, mais comment depuis mon application je récupère ces données ?
Rien de plus simple, nous avons un "API preview", allons dedans et récupérons l'endpoint

Nous devons donc simplement utiliser "/api/collections/products/records"
pour récupérer la liste de nos produits. Nous enverrons la requête avec les bons headers et les bons tokens, et nous récupérerons directement les ressources.
En GET, sur :
https://pocketbase-q4kcocww8s04owowoo0g0gws.andy-cinquin.fr
- donc
https://pocketbase-q4kcocww8s04owowoo0g0gws.andy-cinquin.fr/api/collections/products/records
Nous pouvons donner les droits que nous voulons ici :



et ensuite y accéder directement depuis un fetch classique.
Exemple avec de l'authentification :
Avec un super user pour donner les accès à notre API :


Nous pouvons par exemple récupérer notre token comme ceci :
https://pocketbase-q4kcocww8s04owowoo0g0gws.andy-cinquin.fr/api/collections/_superusers/auth-with-password
Avec comme body :{
"identity": "testtuto@test.test",
"password": "testtuto@test.test"
}
Vos identifiants vous permettront de récupérer ce genre de réponse. Vous utiliserez ensuite ce token dans le bearer pour créer des choses en tant que superadmin (si aucun droit n'a été changé, vous avez besoin de ce token partout quand vous passez par l'API)
Exemple :


Donc sur :
https://pocketbase-q4kcocww8s04owowoo0g0gws.andy-cinquin.fr/api/collections/products
en "POST"
vous pouvez créer ce que vous voulez :


🚀 Merci d'avoir lu jusqu'ici !
Si cet article vous a plu, partagez-le autour de vous.
💡 Une idée en tête ? Discutons-en !☕