Skip to content

Stockage des données

Persister des données

Une application containerisée peut persister ses données. Toute modification au sein du container est stockée dans la layer du container créé au démarrage du container, accessible en lecture / écriture. Lorsque celui-ci est supprimé, ce layer ainsi que tous les fichiers contenus sont automatiquement supprimés. Pour persister les données il est donc indispensable de les gérées en dehors de l'union filesystem

Aufs

Démarrons un container de test et créons un fichier

shell
docker container run -it --name test alpine sh
touch /tmp/toto
exit

Le fichier est visible depuis la machine hôte

shell
find /var/lib/docker -name 'test'

/var/lib/docker/btrfs/subvolumes/736077b34945b9a36795ca77545d45cb6952c3321059623451bbbbc0b1e0e106/tmp/toto

Supprimons maintenant le container

shell
docker container rm test

Le fichier a été supprimé avec le container

shell
find /var/lib/docker -name 'toto'

Les volumes

Les volumes servent à stocker les données à l'extérieur l'union filesystem, c'est à dire à découpler les données du cycle de vie du container. Si un container est supprimé, ses données seront donc toujours présentes.

On utilise par exemple un volume pour le stockage d'une base de données ou encore la persistance de logs en dehors du container.

Un volume peut se définir de plusieurs façons :

  • Via l'instruction VOLUME dans le Dockerfile

Pour illustrer cet exemple, lançons une image mongodb...

shell
docker container run -d --name mongo mongo:7.0.14

...et inspectons son contenu

shell
docker container inspect -f '{{json .Mounts }}' mongo | python -m json.tool

[
  {
     "Type": "volume",
     "Name": "c4df0e1c596d68fcecaaefaa4853ae0e4d04ae4d9df45d2fb6e84188af4b6a43",
     "Source": "/var/lib/docker/volumes/c4df0e1c596d68fcecaaefaa4853ae0e4d04ae4d9df45d2fb6e84188af4b6a43/_data",
     "Destination": "/data/configdb",
     "Driver": "local",
     "Mode": "",
     "RW": true,
     "Propagation": ""
  },
  {
     "Type": "volume",
     "Name": "91aabdd3cb32124bed6c8bc77f6d3b6f944a922c8d78e9117552fd05c0e4bb1a",
     "Source": "/var/lib/docker/volumes/91aabdd3cb32124bed6c8bc77f6d3b6f944a922c8d78e9117552fd05c0e4bb1a/_data",
     "Destination": "/data/db",
     "Driver": "local",
     "Mode": "",
     "RW": true,
     "Propagation": ""
  }
]

On constate qu'il existe deux volumes /data/configdb et data/db qui ont été définis lors de la création de l'image ; dans le Dockerfile suivant : https://github.com/docker-library/mongo/blob/1edf40cdc57f393bb5340c298eb6baa98ae94a5f/5.0/Dockerfile. Les fichiers sont accessibles sur l'hôte dans les répertoires définis par la clé Source.

  • En utilisant l'option -v ou --mount lors de la création du container

Pour définir un volume via l'option -v il suffit de lancer

shell
docker container run -v [CONTAINER_PATH] [IMAGE]

Le principe est le même que l'instruction VOLUME du Dockerfile : les données contenu dans le path du container seront copié sur la machine hôte.

  • Par l'usage de la commande shell docker volume create

Le daemon de docker expose au client cli via son api un ensemble de fonctions :

shell
docker volume --help

Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

Run 'docker volume COMMAND --help' for more information on a command.

Pour se faire Docker propose plusieurs drivers dont le local qui est utilisé par défaut et pour lequel un répertoire est créé sur la machine hôte ; pour chaque volume.

Illustrons cet usage en créant créant un volume :

shell
docker volume create --name db-data

Il est alors visible par le daemon de docker

shell
docker volume ls
shell
docker volume inspect db-data

[
    {
        "CreatedAt": "2021-11-16T05:53:55+01:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/db-data/_data",
        "Name": "db-data",
        "Options": {},
        "Scope": "local"
    }
]

On peut ensuite l'utiliser pour persister les données d'une base de données mongo par exemple

shell
docker container run -d --name db -v db-data:/data/db mongo:7.0.14

Le contenu du répertoire du container est alors visible dans le volume

shell
ls /var/lib/docker/volumes/db-data/_data