Passer d'un bind mount à un volume Docker

Pour stocker les données des services, on préfère utiliser les volumes Docker.

Note:

En particulier, les bind mounts ne sont pas idéaux pour les données :

  • Ils dépendent d’un chemin spécifique et ne sont pas dans la partition allouée à Docker
  • Le comportement des bind mount n’est pas constant quand un dossier non-vide de l’hôte est monté sur un dossier non-vide du conteneur.
  • Docker Compose gère automatiquement le cycle de vie des volumes Docker.
  • Il est facile de vérifier la liste de tous les volumes Docker.

Pour cette exemple, on va supposer la situation suivante :

  • Un service monte le dossier /old_data (hôte) sur /content (conteneur).
  • On veut plutôt utiliser un volume Docker appelé data.

On ne peut pas migrer les données pendant que le conteneur tourne, car elles sont susceptibles d’être modifiées.

Note:

On utilise indifféremment docker stop ou docker-compose stop.

docker volume create data

Il est plus facile de copier les données dans le volume si ce dernier est monté dans un conteneur. On crée donc un conteneur qui ne fait rien et qui monte le volume data sur le dossier /dumb.

docker run -v data:/dumb --name dumb busybox true

Note:

busybox est une très petite image Docker contenant quelques utilisateurs GNU. On lance la commande true, qui ne fait rien. Le conteneur s’éteint, mais on a pas besoin qu’il soit vivant.

Note:

On pourrait tout aussi bien copier directement les données dans /var/lib/docker/volumes/data/_data, qui est le “vrai” chemin du volume, mais cela nécessite les accès root et c’est un peu moins propre.

La commande docker cp permet de copier des dossiers entre conteneurs ou depuis l’hôte. On va donc copier les données du dossier data de l’hôte vers le dossier /dumb du conteneur dumb.

# Remplace /old_data par le dossier concerné
docker cp -a /old_data/. dumb:/dumb

Attention:

Notez le /., essentiel après le nom du dossier, pour ne copier que son contenu!

docker stop dumb && docker rm dumb

On remplacera tout simplement /data_old (chemin d’un dossier sur l’hôte) par data (nom d’un volume).

Si on utilise Compose, il ne faut pas oublier de déclarer data comme volume, par exemple :

snippet.yaml
volumes:
  data:
    name: "data"

services:
  mon_service:
    [...]
    volumes:
      - data:/content
    [...]

Suite à ces modifications, vous pouvez redémarrer le conteneur initial. Les données sont restaurées et sont maintenant gérées dans un volume Docker.

Note:

On utilisera indifféremment docker start ou docker-compose start.

  • technique/docker/admin/bindmount-to-volume.txt
  • de qduchemi