1. Tout le cours repose sur un seul starter repo
Il y a deux façons également mauvaises d'enseigner un sujet d'infrastructure. La première — vivre dans des exemples abstraits qui ne ressemblent pas à un vrai backend. La seconde — obliger l'étudiant à écrire d'abord un tout nouveau service, puis « quelque part vers la fin » lui montrer Docker. Les deux approches volent simplement l'attention à l'essentiel.
Le starter repo résout ce problème de façon très honnête. Il est déjà assez réel pour qu'on y voie le comportement d'un service Boot ordinaire : couche HTTP, configuration, profils, export en fichier, Actuator, signaux techniques. Mais en même temps, il ne se transforme pas intentionnellement en un cours séparé sur le modèle de domaine, JPA, la sécurité ou la messagerie. On a besoin d'un service comme support du sujet conteneurisation, pas comme un nouveau grand domaine.
C'est pourquoi un seul dépôt est méthodologiquement plus fort que cinq « mini-démos ». On ne dépense pas d'énergie à se réacclimater constamment à un nouveau projet, un nouveau package, un nouveau contexte et une nouvelle logique métier. Au lieu de ça, on voit comment une seule et même application mûrit progressivement du point de vue du runtime et de l'infrastructure.
2. Comment lire le dépôt sans se noyer dans les détails
Le premier coup d'œil sur le starter repo doit ressembler non pas à de l'archéologie, mais à la lecture d'une carte. L'important d'abord, c'est de comprendre le niveau supérieur : quels fichiers gèrent le lancement, où se trouvent les requêtes pour des vérifications rapides, où vit le scénario de fichiers, où est le code et quels artefacts apparaîtront à mesure que le cours progresse.
La structure typique de haut niveau ressemble à ceci :
# Racine du dépôt (dossier du projet)
container-ready-catalog-service/
├── Dockerfile # Instructions de construction de l'image Docker (sera utilisé plus tard)
├── compose.yaml # Description Compose de l'environnement (ex. app + BDD)
├── requests/ # Requêtes HTTP rapides pour smoke-checks et vérifications reproductibles
├── scripts/ # Scripts utilitaires pour les opérations répétables autour du service
├── data/exports/ # Répertoire où le service peut écrire des exports (scénario de fichiers)
└── src/main/ # Code source de l'application Spring Boot
Au départ, il ne faut pas percevoir ça comme une liste sèche de fichiers. Chaque élément a son rôle. src/main/ — c'est là que vit l'application elle-même. requests/ — ce sont des vérifications HTTP rapides pour que le baseline soit reproductible non pas « de mémoire », mais concrètement. scripts/ — l'endroit pour les petites opérations répétables autour du service. data/exports/ — un rappel que le service a aussi une vie de fichiers, pas seulement REST. Dockerfile et compose.yaml sont là non par hasard : ils deviendront plus tard la partie conteneurisation de ce même projet.
Un autre point est important ici. On ne lit pas les artefacts Docker avant le temps, mais on voit déjà qu'ils coexistent avec le code. C'est la bonne intuition de projet. La conteneurisation ne devrait pas être une « magie personnelle de l'auteur » dans un dossier séparé avec des scripts incompréhensibles. Elle doit faire partie du même dépôt que le service. ⚙️
3. Le service est très simple
Le domaine du projet a été intentionnellement choisi très tranquille. On a un catalogue d'éléments et un scénario d'export de ce catalogue vers un fichier. C'est exactement ce qu'il faut pour voir sur un seul service plusieurs lignes importantes pour le cours : une API HTTP ordinaire, l'état des données, les modes de lancement, le système de fichiers et les signaux opérationnels.
En clair, le service ne fait pas « tout ce qui existe », seulement ce qui est nécessaire pour le sujet conteneurisation. Il sait retourner la liste des éléments du catalogue, effectuer des opérations de base dessus et lancer l'export. L'objectif ici n'est pas de t'impressionner par la complexité de la logique métier. Au contraire, le domaine est maintenu intentionnellement dans des limites simples pour que l'attention ne s'échappe pas. 🧪
C'est une partie importante de la compréhension. Un bon cours ne prétend pas qu'il faut expliquer la conteneurisation via un demi-backend, une matrice de sécurité, trois microservices et huit tables en base. Un seul service normal avec un comportement clair suffit. Et le Container-Ready Catalog Service est conçu exactement ainsi.
4. standalone et postgres : deux modes
Le starter repo a au moins deux modes de base, et il est très important de les voir dès le premier jour. standalone est fait pour un lancement rapide sans base externe : les données vivent en mémoire, on peut lever le service rapidement et vérifier son comportement HTTP presque immédiatement. postgres est un mode plus réaliste, où le service a une dépendance externe et tout le runtime devient un peu plus adulte.
Le point clé ici est que ce ne sont pas deux applications différentes. On n'a pas un « service docker » séparé et un « service local » séparé. Les contrôleurs, la logique et le caractère général du comportement restent les mêmes. Ce sont les conditions de lancement qui changent. Et c'est une habitude très importante : un seul service, des présupposés d'environnement différents.
Cette même idée traversera tout le cours. Si tu as besoin d'un comportement d'environnement différent, tu ne dois pas cloner le projet ni créer un deuxième chemin de code. Tu dois savoir gérer le runtime d'un seul et même service. C'est là que la pensée conteneurisation commence à paraître mature, et non cosmétique.
5. Le baseline opérationnel minimal
Il est très tentant de considérer un service comme « vivant » sur la base d'un seul fait : le processus n'a pas planté et une ligne de démarrage a clignoté dans les logs. Mais c'est un critère trop faible. Pour un baseline correct, il faut au moins deux signaux : un signal métier et un signal technique.
Le signal métier répond à la question « le service fait-il vraiment ce pour quoi il existe ? ». Pour notre starter repo, GET /api/catalog/items fonctionne parfaitement comme tel. Le signal technique répond à « l'application a-t-elle réellement démarré et peut-elle signaler honnêtement son état ? ». Pour ça, il faut GET /actuator/health.
C'est exactement cette paire qui donne un bon baseline de smoke-check. Si l'endpoint métier répond, le web-layer et a minima la logique sont vivants. Si le health répond, le service a au moins un contrat opérationnel de base. Ensemble, ces deux vérifications donnent un sentiment bien plus honnête de « le service est démarré » que le simple fait que le processus Java n'ait pas encore terminé.
Au premier niveau, c'est déjà suffisant. On n'a pas besoin de templates de diagnostic complexes ni d'un approfondissement d'Actuator. Pour l'instant, il est utile de voir une seule chose : un service vivant, ce n'est pas juste « n'a pas planté », mais « répond aux signes clés de vie ».
6. Plan pour aujourd'hui 🍹
On peut maintenant faire une toute petite action qui donne le premier résultat tangible sans surcharge. D'abord, lance le starter repo localement de la façon qui t'est déjà habituelle dans un projet Spring Boot. On n'a pas besoin d'un nouveau workflow de build pour l'instant — il s'agit juste d'obtenir un baseline local fonctionnel.
Ensuite, fais deux vérifications rapides. Si tu utilises le port standard, elles peuvent ressembler à ça :
# On vérifie l'endpoint métier : le service retourne vraiment les données du catalogue
curl http://localhost:8080/api/catalog/items
# On vérifie l'état technique : Actuator indique que l'application est "vivante"
curl http://localhost:8080/actuator/health
Si tu préfères travailler via Postman ou des fichiers .http, tu peux utiliser les fichiers du dossier requests/ du dépôt — l'idée est la même. La première vérification répond à « l'endpoint métier est-il vivant ? », la deuxième — « le service se voit-il lui-même comme une application vivante ? ».
Voilà le premier résultat significatif de la journée. Tu n'as pas encore construit d'image, pas écrit de Dockerfile et pas lancé Compose, mais tu sais déjà regarder le starter repo comme un objet opérationnel, pas comme un dossier de code. Et c'est un très bon départ pour un cours Docker.
7. Fiche de baseline avant la conteneurisation
Voici une fiche qu'on peut utiliser non seulement pour ce projet, mais pour presque n'importe quel service Boot futur. Elle aide à ne pas sauter dans Docker trop tôt et à fixer rapidement ce qu'on va conteneuriser exactement.
| Ce qu'il faut demander à tout service Boot avant la conteneurisation | Comment ça se présente dans Container-Ready Catalog Service |
|---|---|
| Qu'est-ce qui démarre exactement ? | Application Spring Boot avec un point d'entrée clair |
| Quel smoke-check business minimal ? | GET /api/catalog/items |
| Quel smoke-check technique minimal ? | GET /actuator/health |
| Quels modes de lancement faut-il distinguer ? | standalone et |
| Quels présupposés externes existent déjà ? | Port, en mode postgres — une base, pour l'export — un répertoire |
| Où chercher la première confirmation opérationnelle ? | Logs de démarrage + réponses aux deux endpoints |
Ça paraît un tableau simple, mais en pratique il économise beaucoup d'énergie. Dès qu'on sait répondre rapidement à ces questions, la conteneurisation cesse d'être un saut dans le brouillard. On a déjà un baseline, et Docker ensuite ne le remplacera pas, mais le stabilisera.
8. L'échelle d'évolution du projet
Et maintenant ce qui est le plus agréable : on peut voir le cours comme une ligne continue, pas comme un ensemble de sujets. Voici une carte courte de la façon dont ce même Container-Ready Catalog Service va évoluer :
| Étape | Ce qui change dans ce même service | Ce qu'on obtient |
|---|---|---|
| Maintenant | Baseline Spring Boot local + smoke-check | Un objet de conteneurisation clair |
| Ensuite | Première image et premier container | Un runtime reproductible pour un seul service |
| Puis | Dockerfile correct, cache, multi-stage, layers, buildpacks | Un empaquetage professionnel du service Java |
| Après | Config externalisée, fichiers, logs, health, shutdown | Un comportement contrôlé d'une seule image dans différents modes |
| Puis encore | app + PostgreSQL via Compose | Un vrai environnement backend local |
| Plus loin | Ajout de Redis et RabbitMQ | La capacité de vivre avec des dépendances infrastructure sans chaos |
| Fin | Template réutilisable et compétence d'analyse systémique des problèmes | Un baseline reproductible pour ses propres services |
Un seul et même service parcourt tout le chemin — du lancement local au template mature côté conteneurisation. Et grâce à ça, chaque étape suivante se ressent non pas comme un nouveau sujet à partir de zéro, mais comme la continuation naturelle d'un contexte déjà connu.
S'il ne faut retenir qu'une chose après la première journée, que ce soit celle-ci : ce qu'on conteneurise, c'est non pas Docker pour Docker, mais un service Spring Boot concret avec un baseline clair. Demain, ce baseline va déjà commencer à se transformer en objet d'ingénierie avec son propre cycle de vie, ses logs et son comportement observable dans l'environnement conteneurisé.
9. Erreurs classiques 🚧
Erreur n° 1 : lire le starter repo comme un ensemble de dossiers aléatoires.
Il faut toujours d'abord une carte de haut niveau : où est le code, où sont les requêtes, où est le scénario de fichiers, où sont les futurs artefacts de conteneurisation. Si on commence directement à se noyer dans les classes et les packages, on perd très facilement le sens pédagogique du projet.
Erreur n° 2 : percevoir standalone et postgres comme deux applications différentes.
C'est un seul service, pas deux bases de code parallèles. Ce sont les conditions de sa vie qui diffèrent, pas sa nature. Cette pensée sera critique plus tard pour la configuration conteneurisée et Compose.
Erreur n° 3 : considérer un service comme « vivant » uniquement sur la base du démarrage du processus.
Un processus peut démarrer sans avoir de comportement utile. C'est pourquoi il vaut mieux toujours fixer le baseline minimal avec au moins une paire de requêtes : endpoint métier plus endpoint health.
Erreur n° 4 : regarder Dockerfile et Compose avant de comprendre le service lui-même.
C'est un piège très fréquent. On veut passer directement à la « partie conteneurisation intéressante », mais sans baseline local elle se transforme en jeu de devinettes. D'abord, il faut comprendre ce qu'on conteneurise exactement et par quels signaux on saura que le service est vivant.
GO TO FULL VERSION