{{indexmenu_n>60}}
# Passer d'un bind mount à un volume Docker
## Préambule
Pour stocker les données des services, on [[technique:docker:good_practices:storage|préfère utiliser les volumes Docker]].
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`.
## Procédure
### Arrêter le conteneur
On ne peut pas migrer les données pendant que le conteneur tourne, car elles sont susceptibles d'être modifiées.
On utilise indifféremment `docker stop` ou `docker-compose stop`.
### Création du volume
```
docker volume create data
```
### Monter le volume
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
```
`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.
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.
### Copier les données
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
```
Notez le `/.`, essentiel après le nom du dossier, pour ne copier que son contenu!
### Arrêter le conteneur de copie
```
docker stop dumb && docker rm dumb
```
### Modifier le point de montage
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 :
```yaml
volumes:
data:
name: "data"
services:
mon_service:
[...]
volumes:
- data:/content
[...]
```
### Redémarrage du conteneur
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.
On utilisera indifféremment `docker start` ou `docker-compose start`.