Docker

Docker : migrer les données d’un Bind Mount vers un Volume

J’ai longtemps utilisé les « Bind Mount » dans la gestion de mes conteneurs sous Portainer. Aussi j’ai récemment découvert la possibilité de créer des volumes via NFS. Me voilà avec une question : comment migrer les données d’un Bind Mount vers un Volume Docker.

La procédure vous permet de migrer vos données en toute sérénité. Pour le contexte, j’utilise docker-compose avec portainer. La procédure reste cependant la même. Portainer ou non. Si vos conteneurs sont déclarés en CLI, le principe reste le même, mais je vous conseille de passer vos conteneurs sous stack docker-compose.

Tout au long de l’article, je prend comme exemple une stack Wordpress.

Définition « Bind Mount » et « Volume »

Voici un Bind Mount ou mappage de répertoire. Ici je map un dossier de la machine hôte vers un répertoire du conteneur.

volumes:
   - /srv/docker/wp-demo/html:/var/www/html

Ici, je map un volume docker vers un répertoire du conteneur. Par défaut, docker stocke le contenue des volumes dans `/var/lib/docker/volumes/`

Lors de la création du volume au déploiement de la stack, la volume prendra comme nom : « STACK_NAME_VOLUME_NAME ». Dans mon cas la stack est nommé « wp-demo », le volume ci dessous sera nommé « wp-demo_html »

volumes:
    - html:/var/www/html

Cet article explique très bien la différence et les cas d’utilisation des deux méthodes.

Migrer les données d’un Bind Mount vers un Volume

La première étape est simple, éteignez vos conteneurs pour éviter des corruptions de fichiers.

Ensuite il nous faut créer nos volumes, dans mon cas je modifie ma stack docker-compose de mon portainer pour déclarer et utiliser les volumes. La stack me les crée automatiquement.

Stack en Bind Mount :

version: "2"
services:
   wordpress-db:
     container_name: wordpress-db
     image: mysql:5.7
     volumes:
       - /srv/docker/wp-demo/db:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD: root-password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: utilisateur
       MYSQL_PASSWORD: password
 
   wordpress:
     container_name: wordpress
     depends_on:
       - wordpress-db
     image: wordpress:latest
     ports:
       - 1080:80
     volumes:
       - /srv/docker/wp-demo/html:/var/www/html
     environment:
       WORDPRESS_DB_HOST: wordpress-db:3306
       WORDPRESS_DB_USER: utilisateur
       WORDPRESS_DB_PASSWORD: password
       WORDPRESS_DB_NAME: wordpress

Stack avec des volumes :

version: "2"
services:
   wordpress-db:
     container_name: wordpress-db
     image: mysql:5.7
     volumes:
       - db:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD: root-password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: utilisateur
       MYSQL_PASSWORD: password
 
   wordpress:
     container_name: wordpress
     depends_on:
       - wordpress-db
     image: wordpress:latest
     ports:
       - 1080:80
     volumes:
       - html:/var/www/html
     environment:
       WORDPRESS_DB_HOST: wordpress-db:3306
       WORDPRESS_DB_USER: utilisateur
       WORDPRESS_DB_PASSWORD: password
       WORDPRESS_DB_NAME: wordpress
       
volumes: 
  db:
  html:

On aperçoit la déclaration des volumes en bas de la stack, tout comme je déclare les conteneurs (services). Aussi dans les chemins « volumes: » je met le nom des volumes déclarer à la place du chemin de répertoire de l’hôte.

Une fois la stack déployer, identifiez les volumes créer à l’aide de portainer ou de la commande `docker volumes ls`

Inspecter le volume pour connaître son point de montage (Mountpoint) avec portainer ou en CLI :

docker inspect volume wp-demo-html

La commande ressort quelque chose comme :

[
    {
        "CreatedAt": "2022-10-27T21:31:59+02:00",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "wp-demo",
            "com.docker.compose.version": "2.5.1",
            "com.docker.compose.volume": "html"
        },
        "Mountpoint": "/var/lib/docker/volumes/wp-demo_html/_data",
        "Name": "wp-demo_html",
        "Options": null,
        "Scope": "local"
    }
]

Le « Mountpoint » est l’endroit où nous allons copier nos données.

Arrêter de nouveau la stack docker-compose pour procéder à la migration.

Il faut comprendre que l’on créer des volumes précédemment, par conséquent le conteneurs à générer des fichiers dans le volume. Notre but étant de migrer nos données existantes, il faut supprimer les données existantes du volume puis déplacer les données du Mountpoint.

Adapter les chemins de fichiers et le mountpoint selon votre infrastructure.

rm -r /var/lib/docker/volumes/wp-demo_html/_data/*
cp -r /srv/docker/wp-demo/html/* /var/lib/docker/volumes/wp-demo_html/_data

La stack wordpress à également un volume « db », je fait le même process :

rm -r /var/lib/docker/volumes/wp-demo_db/_data/*
cp -r /srv/docker/wp-demo/db/* /var/lib/docker/volumes/wp-demo_db/_data

Il ne reste qu’à démarrer votre stack, et le tour est joué !

Jérémy Taunay

🪪 Be smarter everyday | 🏮 Less is more | 🐧Tech systèmes et réseaux | 🖥️ Homelaber