Faire écrire Mini-Carnet sur disque

Jusqu'ici, le compteur de visites de Mini-Carnet n'existait qu'en mémoire, dans une simple variable JavaScript. Faisons-le évoluer pour qu'il écrive réellement ce compteur dans un fichier, avec le module fs de Node.js, déjà inclus sans installation supplémentaire :

Reconstruisez l'image pour prendre en compte ce changement, comme appris au guide 15 :

Constatez le problème vous-même

Lancez un conteneur, visitez la page plusieurs fois, puis supprimez ce conteneur et recréez-en un nouveau, exactement identique :

Rafraîchissez http://localhost:3000 : le compteur repart de 1. Toutes les visites précédentes ont disparu, alors que vous avez utilisé exactement la même image.

Pourquoi ça se passe ainsi

Rappelez-vous du guide 3 : un conteneur est une instance jetable, créée à partir d'une image immuable. Tout ce qu'un conteneur écrit pendant son fonctionnement, comme le fichier visites.txt ici, vit uniquement dans une couche d'écriture propre à ce conteneur précis, pas dans l'image. Supprimer le conteneur supprime cette couche d'écriture avec lui, et donc tout ce qu'il avait écrit.

La solution : un volume Docker

Un volume est un espace de stockage géré par Docker, qui existe indépendamment du cycle de vie d'un conteneur précis. Un dossier du conteneur peut être relié à un volume : tout ce qui y est écrit survit alors à la suppression du conteneur, et peut être retrouvé par un nouveau conteneur relié au même volume.

Supprimez le conteneur actuel, et relancez-en un nouveau avec l'option -v, qui relie cette fois un volume nommé au dossier data de l'application :

mini-carnet-data est le nom que vous donnez à ce volume. /app/data est le chemin, à l'intérieur du conteneur, relié à ce volume : c'est exactement le dossier data créé par server.js, puisque WORKDIR vaut /app depuis le guide 11.

Visitez la page plusieurs fois, puis répétez le test précédent : supprimez le conteneur, recréez-en un avec la même option -v mini-carnet-data:/app/data. Cette fois, le compteur continue là où il s'était arrêté : le volume, lui, n'a jamais été supprimé.

Volume nommé ou bind mount ?

Ce guide utilise un volume nommé (mini-carnet-data) : Docker gère lui-même l'emplacement réel de ces données sur votre disque, vous n'avez pas besoin de le connaître. Il existe une seconde approche, le bind mount, qui relie un dossier précis de votre propre ordinateur à un dossier du conteneur, avec une syntaxe très proche (-v /chemin/sur/votre/pc:/app/data). Un bind mount est surtout utile pendant le développement, pour voir un fichier modifié sur votre ordinateur reflété immédiatement dans le conteneur. Pour conserver des données comme ici, un volume nommé reste le choix le plus simple et le plus recommandé.

Vérifiez que vous avez compris

Vous supprimez le volume mini-carnet-data lui-même avec docker volume rm mini-carnet-data, puis vous relancez un conteneur relié à ce même nom de volume. Le compteur de visites va-t-il repartir de zéro ?

Oui. Supprimer explicitement le volume détruit les données qu'il contenait, y compris visites.txt. Docker recréera simplement un nouveau volume vide portant le même nom au prochain docker run, mais sans aucune des données précédentes : un volume protège les données de la suppression d'un conteneur, pas de la suppression volontaire du volume lui-même.