virli/tutorial/1/volumes.md
2017-09-22 10:27:49 +02:00

4.2 KiB

\newpage

Volumes

Il est possible de partager des répertoires entre plusieurs conteneurs. Pour ce faire, il faut déclarer dans le Dockerfile une ou plusieurs instructions VOLUME avec le chemin du répertoire à considérer comme volume (il est également possible de le faire via l'option --volume du client). Ces deux lignes sont équivalentes :

VOLUME /var/log/nginx
docker run -v /var/log/nginx my_nginx

Pour monter les volumes dans un autre conteneur, on utilise l'argument --volume-from du client, en indiquant le nom du conteneur avec lequel on souhaite partager les volumes :

docker run -it --volume-from romantic_archimedes ubuntu /bin/bash

Vous constaterez que le répertoire /var/log/nginx est partagé entre romantic_archimedes et le dernier conteneur lancé. \newline

Le concept principal de Docker est de concevoir des conteneurs applicatifs : on va préférer assigner un unique rôle à un conteneur (donc géralement on ne va lancer qu'une seule application par conteneur) et concevoir un service complet en créant un groupe de conteneur, partageant des données entre-eux par des volumes.

Une lecture intéressante sur ce sujet est sans doute cet article de Michael Crosby.

Partage avec la machine hôte

Il est possible de monter un répertoire de la machine hôte dans un conteneur. L'intérêt reste plutôt limité à des fins de facilité ou de test, par exemple si vous voulez partager des fichiers avec votre voisin, en passant par le protocole HTTP, mais sans se casser la tête à installer et configurer un serveur web :

docker run --rm -p 80:80 -v ~/Downloads:/usr/share/nginx/html:ro -d nginx

Une fois cette commande lancée, votre voisin pourra accéder à votre dossier Downloads en renseignant l'IP de votre machine dans son navigateur favori !

Data Volume Container

Dans de nombreuses situations, il est intéressant de séparer les données de l'application, et donc d'avoir un conteneur exécutant l'application et un second stockant les données.

Cela est particulièrement utile dans le cas d'une base de données : on veut pouvoir mettre à jour le conteneur exécutant le serveur, sans pour autant perdre les données.

L'idée derrière le concept de Data Volume Container est de partager un volume avec un conteneur dont le seul rôle est de stocker les données.

Il est parfaitement possible de partager un volume avec un conteneur qui n'est plus lancé. En effet, tant que vous n'avez pas demandé explicitement à un conteneur d'être supprimé, il est préservé dans un coin en attendant des jours meilleurs.

Voici comment on pourrait lancer un conteneur exécutant une base de données :

docker create -v /var/lib/mysql --name dbdata busybox /bin/true
docker run --volume-from dbdata -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql

Le premier conteneur, sans commande passée, va s'arrêter dès son lancement. Busybox est l'une des plus petites images possédant tous les outils de base (il est possible d'obtenir un shell en cas de besoin). Il expose un volume qui sera utiliser comme stockage persistant.

Le second conteneur va lancer le serveur MySQL et utiliser le répertoire partagé pour stocker les données.

Lorsqu'il y aura besoin de mettre à jour le conteneur MySQL, les données ne seront pas perdues (et s'il y avait besoin de migrer les données entre les deux versions des conteneurs, un conteneur intermédiaire pourrait parfaitement s'en charger).

Cela facile également les sauvegardes, qui peuvent s'exécuter dans un conteneur distinct, dédié à la tâche de sauvegarde.

Rendu

Exercice

Modifiez le Dockerfile de l'exercice précédent pour que votre application web (ok, c'est juste un index.html ...) soit contenue dans un data volume container.

Choisissez le nom de votre volume judicieusement, cela peut vous faciliter la vie !

Écrivez un script shell qui reprend les commandes que vous avez tapé dans votre terminal pour créer le data volume container, construire l'image à partir du Dockerfile et lancer le conteneur my_webserver lié.

Rendre le Dockerfile, son contexte et le script de construction/lancement.