Il y a bien un truc qui peu déstabiliser quand on débute avec Docker, c'est les volumes. Personnellement ça m'a un peu gonflé quand j'ai commencé. 😅
C'est pourquoi je me suis dit qu'on pourrait en discuter de la manière la plus simple et compréhensible possible.
Si cela vous tente, on va démêler tout ça! Il y a des variantes qui ne seront pas expliquées car le principe c'est vraiment de comprendre un minimum les volumes sans s'embrouiller. Enfin, j'espère.
Rappel sur l'utilité et la raison d'être des volumes : assurer la persistance des données stockées.
Il faut se dire qu'il y a deux façons d'assurer la persistance de vos données, autrement dit de créer des dossiers qui vont contenir vos données:
- les volumes docker
- les bind mounts
Voici, sous forme de tableau les principales différences. Nous verrons plus loin comment ça se présente dans un docker-compose.
Docker Volumes | Bind Mounts |
---|---|
Les volumes Docker sont gérés par Docker et sont généralement stockés dans un répertoire spécifique sur la machine hôte. | Les bind mounts font référence à un répertoire sur la machine hôte. Le répertoire est directement monté dans le conteneur à un chemin spécifié. |
Les volumes sont indépendants du cycle de vie du conteneur et peuvent être créés, gérés et partagés sur plusieurs conteneurs. | Les bind mounts sont étroitement couplés au système de fichiers hôte et n'ont pas les mêmes fonctionnalités et flexibilité que les volumes Docker. |
Les volumes offrent plus de fonctionnalités, telles que les commandes de gestion des données et l'intégration avec les outils de l'écosystème Docker. | Les bind mounts sont utiles lorsque vous devez accéder directement à des fichiers ou des répertoires depuis l’hôte dans le conteneur. |
Ce tableau est issu de ce site, je n'ai fait que le traduire.
Donc pour résumer au minima du minima:
- les volumes docker => les dossiers ne sont pas montés dans le container même => si vous supprimez le dossier de votre container vos données ne sont pas effacées dans la foulée vu qu'elles ne se trouvent pas dedans.
- les bind mounts => les dossiers sont directement montés dans le container => si vous supprimez le dossier du container pour une raison ou une autre, il faudra veiller à déplacer vos données avant sans quoi tout est perdu.
Maintenant voyons comment cela se traduit dans un docker-compose.
La majorité du temps vous allez tomber sur trois cas de figure. Pour illustrer cela, nous allons prendre le même docker-compose et l'adapter pour chaque situation.
Prenons le docker-compose de Homarr. Il est simple, pas trop long ni compliqué, notre attention sur les volumes sera ainsi facilitée.
Attention, un docker-compose simple ne veut absolument pas dire que l'application n'est pas bonne ou simple.
Cas de figure numéro 1
Ici nous sommes dans le cas d'un bind mounts, les données sont montées dans le container.
version: '3'
services:
homarr:
container_name: homarr
image: ghcr.io/ajnart/homarr:latest
restart: unless-stopped
volumes:
- ./homarr/configs:/app/data/configs
- ./homarr/icons:/app/public/icons
- ./homarr/data:/data
ports:
- '7575:7575'
Dans cette configuration, on voit que l'indication de où doivent se trouver les données commence par ./, à première vue cela ne donne pas beaucoup d'indices pour comprendre où vont être stockées ces maudites données...
En réalité, la solution est toute simple: tout dépend dans quel répertoire vous vous trouvez. En effet, il suffit de penser quand vous voyez ça: "Quand je vais lancer mon docker-compose, cela va créer les dossiers qui suivent ./ dans le dossier dans lequel je me trouve."
Prenons l'exemple que vous voyez dans les tutoriels de belginux, qui est purement arbitraire: /srv/appdata.
Pour m'y retrouver, je réunis toutes mes applications dans un dossier qui se nomme appdata.
Donc si je déploie ce docker-compose dans le dossier /appdata, le dossier homarr sera créé dans: /srv/appdata, ce qui va donner /srv/appdata/homarr, et évidemment dans ce dossier homarr vont-être créés:
- configs
- icones
- data
Donc l'endroit d'où vous déployez votre docker-compose est important. Ne vous trompez pas. 😀
En image cela donne ceci:
Je fais la commande ls pour lister le contenu du dossier ou je me trouve:
On voit clairement qu'il n'y a pas de dossier homarr. Maintenant je crée mon docker-compose:
Et je colle mon docker-compose:
Maintenant je vais le déployer:
Une fois que c'est terminé, je fais à nouveau ls pour lister le contenu:
On constate que le dossier homarr a bien été créé! Allons voir dedans:
Non seulement le dossier homarr a bien été créé, mais ses sous-dossiers également.
Cas de figure numéro 2
Ici nous sommes toujours dans le cas d'un bind mounts, les données sont dans le container.
Un autre exemple, qui est celui que vous trouverez dans la majorités des tutoriels sur belginux et d'autres sites parfois également:
version: '3'
services:
homarr:
container_name: homarr
image: ghcr.io/ajnart/homarr:latest
restart: unless-stopped
volumes:
- /srv/appdata/homarr/configs:/app/data/configs
- /srv/appdata/homarr/icons:/app/public/icons
- /srv/appdata/homarr/data:/data
ports:
- '7575:7575'
Cette façon ne laisse aucun doute possible, le chemin du dossier est complet et quelque soit le dossier d'où vous lancez votre docker-compose, cela n'a pas d'importance, il va créer homarr (et ses sous-dossiers) dans /srv/appdata.
Docker n'étant pas stupide, ce qui est déjà créé comme dossiers, il va simplement se dire ok, ça existe déjà, je vais passer au suivant et créer ceux qui manquent.
On supposant que srv et appdata soient déjà en place, Docker va comprendre qu'il doit simplement créer homarr et ses sous-dossiers afin que le chemin corresponde à ce qu'on lui a demandé dans le docker-compose.
En image cela donne:
J'ai donc effacé le dossier homarr:
Je vais éditer mon docker-compose:
Maintenant je vais le déployer et faire un ls:
Comme tout à l'heure, le dossier homarr est bien créé. Vous allez me dire, oui mais il n'y a pas de différence finalement? Et bien vous avez raison, les deux façons parviennent au même résultat. Ce n'est qu'une toute petite nuance entre ./ et le chemin complet.
Cas de figure numéro 3
Ici nous sommes dans le cas d'un docker volumes. Excepté pour le dossier config. N'en tenez pas compte.
Et maintenant le dernier cas, peut-être bien le plus "perturbant":
version: '3'
services:
homarr:
container_name: homarr
image: ghcr.io/ajnart/homarr:latest
restart: unless-stopped
volumes:
- ./homarr/configs:/app/data/configs
- homarr-icons:/app/public/icons
- homarr-data:/data
ports:
- '7575:7575'
volumes:
homarr-icons:
homarr-data:
Ici les volumes pour icons et data sont les volumes qui vont contenir de données.
Voyons de plus près:
- homarr-icons:/app/public/icons
- homarr-data:/data
Qui sont liés à:
volumes:
homarr-icons:
homarr-data:
Généralement ces deux indications vont de pair.
Si non quand vous allez déployer le docker-compose, et bien il va refuser de faire quoi que ce soit. Vous aurez un message de ce type:
Cette façon de renseigner les volumes indique à votre docker-compose qu'il doit créer les volumes de données dans le dossier volumes qui se trouve ou est installé Docker:
/var/lib/docker/volumes
À l'instar du cas de figure numéro 2, cela n'a aucune importance d'où vous lancer votre docker-compose.
Maintenant voyons tout ceci en image:
Je pars à nouveau sans homarr d'installé:
Je vais éditer mon docker-compose pour qu'il corresponde à notre exemple de docker volumes:
Maintenant je vais déployer le docker-compose.
Le dossier d'homarr a bien été créé:
MAIS, dedans, il n'y a plus que le dossier configs pour le fichier config:
Les données sont bien dans /var/lib/docker/volumes
Conclusion
Quelle est la meilleure méthode? Et bien c'est, pour ma part, un peu difficile à trancher, les deux ont des avantages et des inconvénients.
Quand on débute, ce qui est certain, c'est que c'est plus simple d'avoir tout au même endroit avec un chemin de dossier bien défini.
Les plus confirmés ou, voir les pros, vont généralement préférer la méthode docker volumes (ce que je remarque régulièrement). Cela à du sens si on part du postulat que si, par exemple, on a un dossier avec toutes nos photos, il vaut mieux que ce dossier soit hors du container, comme ça si jamais vous vouliez changer d'application photo, vous n'avez qu'à détruire le dossier du container et installer une autre application en lui indiquant les docker volumes.
Personnellement, les applications que j'utilise, je les utilise car j'en ai testé pleins d'autres et je sais que je vais me fixer un moment dessus, donc pour faciliter le tout, y compris mes backup, j'utilise la méthode bind mounts. Mais c'est un choix personnel et cela n'engage que moi. Même sans ça, je test en profondeur une application et quand elle me plaît, j'ajoute mes données par après vu que j'ai plusieurs backups sur des disques durs.
Le principal est de se faire plaisir avec notre petit serveur et d'évoluer à son aise. De toute facçon que vous choisissiez les docker volumes ou les blind mounts, à l'utilisation vous ne remarquerez aucune différence.
Je ne suis pas un professionnel mais j'essaye de ne pas trop chier dans la colle non plus.
J'espère que c'est un peu plus clair pour vous, n'hésitez jamais à diversifier vos sources pour apprendre et comprendre. D'ailleurs voici un lien qui peut-être bien complémentaire:
Si jamais...
Si vous avez la moindre difficulté, n'oubliez pas que vous pouvez rejoindre belginux sur Discord et Matrix!
Bonne journée à toi.