Guide · VPS & hosting

Construire un SaaS avec IA et Docker : une architecture simple à vérifier

Un tutoriel pour conteneuriser une application SaaS avec une frontière claire entre interface, API, données et fournisseur IA.

Construire un SaaS avec IA ne commence pas par un agent autonome. Commencez par une application web petite, un endpoint serveur qui contrôle les entrées, une base de données isolée et un conteneur reproductible. Docker aide à rendre l’environnement cohérent, mais ne remplace ni l’authentification, ni la validation, ni la gestion des secrets.

Ce que vous allez apprendre

Vous allez découper une application en services, créer une image de développement, limiter l’appel à l’IA côté serveur et vérifier le démarrage local. L’exemple reste volontairement générique : il ne choisit pas de fournisseur, n’inclut pas de prix et ne transforme pas une clé de test en secret public.

Prérequis

Installez Docker et Docker Compose sur votre poste. Préparez un projet Next.js ou une application web équivalente, un fichier d’environnement non versionné et une commande de test connue. Vous devez aussi connaître la différence entre une variable disponible au navigateur et une variable uniquement disponible sur le serveur. Une clé d’API IA ne doit jamais être exposée dans un bundle client ou dans un dépôt Git.

Étape 1 : séparer les responsabilités

Pour un premier produit, gardez quatre frontières : l’interface, l’API applicative, la base de données et le service IA externe. Le navigateur parle à votre API ; votre API valide la session, la requête et les limites ; elle seule appelle le fournisseur IA. La base conserve uniquement les données nécessaires au produit, avec un compte et des permissions adaptés.

Cette séparation évite un anti-pattern courant : appeler directement un modèle depuis le navigateur. Une telle architecture expose la clé, empêche un contrôle central du débit et rend difficile la traçabilité des actions. Même si l’interface n’affiche qu’un champ de texte, l’entrée utilisateur doit être traitée comme une donnée non fiable.

Vérification : cherchez votre clé dans le code client et dans les variables préfixées pour l’exposition navigateur. Elle ne doit apparaître nulle part. Vérifiez aussi qu’un appel IA passe par une route serveur identifiable.

Étape 2 : créer une image reproductible

Un Dockerfile décrit l’environnement qui exécute votre application. Épinglez une image de base adaptée au runtime du projet, copiez d’abord les manifests de dépendances, installez les dépendances puis copiez le code. Cette organisation permet de réutiliser les couches lorsque le code change sans modifier les dépendances.

Utilisez un fichier .dockerignore pour exclure les dépendances locales, les caches, les journaux, les secrets et les fichiers de build inutiles. Le contexte envoyé à Docker doit être le plus petit possible. Ne copiez pas un .env dans l’image : une image peut être partagée, inspectée ou conservée longtemps.

Vérification : construisez l’image depuis un environnement propre, puis inspectez les fichiers présents dans le conteneur. Confirmez que les secrets et les dossiers de travail locaux en sont absents.

Étape 3 : décrire les services avec Compose

Compose permet de déclarer les services locaux et leurs relations. Un premier fichier peut contenir l’application et une base de développement. Donnez à la base un volume persistant local ; donnez à l’application une variable qui pointe vers le service de base, sans réutiliser les identifiants d’un environnement réel. Les réseaux par défaut de Compose suffisent généralement pour une démonstration locale ; n’exposez au poste que les ports nécessaires.

Exemple de démarrage, à adapter aux scripts réels du projet :

docker compose up --build

Ne copiez pas cette commande dans une production sans un fichier et des variables propres à cet environnement. Le même compose.yaml n’est pas automatiquement une configuration de déploiement sûre.

Vérification : ouvrez l’interface locale, appelez une route saine et vérifiez que la base est accessible depuis l’application mais pas nécessairement depuis tous les services.

Étape 4 : contrôler la route IA côté serveur

Une route IA doit vérifier l’identité de l’utilisateur, la taille et le type de l’entrée, puis appliquer une limite d’usage adaptée. Préparez un prompt ou une instruction système dans le code serveur, et placez les données utilisateur dans un champ clairement séparé. Le modèle peut produire du texte ; il ne doit pas recevoir de permissions lui permettant de modifier la base, déployer l’application ou contacter un service arbitraire.

Définissez aussi les erreurs : clé absente, fournisseur indisponible, entrée invalide, quota local atteint. Retournez un message utilisable au client et conservez dans les journaux une catégorie d’erreur, pas le secret ni tout le contenu de la conversation.

Vérification : testez une requête valide, une requête vide et une requête trop longue. Dans les deux derniers cas, aucun appel au fournisseur IA ne doit être fait.

Étape 5 : préparer les migrations et les sauvegardes

La base est un service distinct, même dans un petit SaaS. Les migrations doivent être exécutées par une commande contrôlée et versionnée, pas automatiquement à chaque démarrage sans comprendre la cible. Testez une restauration avec des données de démonstration avant de considérer les sauvegardes comme opérationnelles.

Gardez les utilisateurs, rôles, limites et enregistrements métier séparés des journaux techniques. Cette organisation facilite la suppression, la conservation limitée et la revue des accès. Si vous ajoutez plus tard une file de tâches ou du stockage de fichiers, créez une frontière de service supplémentaire au lieu de surcharger le conteneur web.

Vérification : créez un enregistrement de test, arrêtez et redémarrez les services, puis vérifiez le comportement du volume. Faites ce test uniquement avec des données locales non sensibles.

Problèmes fréquents et solutions

L’application fonctionne hors Docker mais pas dans le conteneur

Comparez la version du runtime, les variables d’environnement, le port écouté et le répertoire de travail. N’installez pas des paquets dans un conteneur à la main pour « réparer » : corrigez le Dockerfile ou les manifests afin que le build soit reproductible.

La clé IA apparaît dans le navigateur

Retirez-la immédiatement du code client et de l’historique accessible, puis remplacez-la selon la procédure du fournisseur. Passez l’appel par une route serveur et contrôlez les variables exposées.

Une requête IA bloque toute l’interface

Définissez un délai, une réponse d’erreur et, si le produit le justifie, une file contrôlée. Un mécanisme asynchrone doit conserver un identifiant de tâche et un état lisible, pas seulement promettre que le modèle « finira plus tard ».

FAQ

Docker est-il obligatoire pour un SaaS IA ?

Non, mais il facilite la reproductibilité des environnements. Les principes de validation, de secrets et de séparation restent nécessaires sans Docker.

Peut-on appeler le modèle directement depuis Next.js ?

Oui depuis une route ou action exécutée côté serveur, pas avec une clé exposée au navigateur.

Faut-il commencer avec plusieurs microservices ?

Non. Commencez avec peu de services et des frontières claires. Ajoutez une séparation seulement lorsqu’un besoin d’exploitation, de sécurité ou de charge le justifie.

Compose suffit-il pour la production ?

Compose peut être un outil de déploiement dans certains contextes, mais il ne couvre pas automatiquement secrets, sauvegardes, supervision, TLS et procédures de restauration.

Comment tester l’endpoint IA sans utiliser de crédits ?

Injectez un client simulé dans les tests. Vérifiez la validation et les erreurs sans appeler un fournisseur externe.

Conclusion

Un SaaS IA maintenable sépare interface, contrôle serveur, données et appel IA. Docker rend le démarrage plus reproductible ; les tests, permissions et secrets rendent le produit exploitable.

Sources et limites

Les réglages Docker et Next.js évoluent selon les versions. Ce tutoriel ne remplace ni une revue de sécurité, ni une procédure de déploiement, ni un plan de sauvegarde validé.