Aller au contenu principal

2.08 Volumes Docker Créer Lister Détruire

Objectifs pédagogiques

  • Savoir utiliser les commandes network (create, ls, rm, prune)
  • Savoir monter des volumes de persistance locaux et distants

Les volumes Docker via la sous-commande volume

  • docker volume create
  • docker volume ls
  • docker volume inspect
  • docker volume rm
  • docker volume prune

Un volume nommé avec la commande create

On crée un volume nommé avec

$ docker volume create redis_data
$ docker run --rm -d -v redis_data:/data redis

Ici le point de montage /data est spécifique à l'image redis

$ docker image history redis 
...
<missing> 2 days ago /bin/sh -c #(nop) VOLUME [/data] 0B
<missing> 2 days ago /bin/sh -c mkdir /data && chown redis:redis … 0B
...

Partager des données avec un volume

Pour partager des données on peut monter le même volume dans plusieurs conteneurs.

Pour lancer un conteneur avec les volumes d'un autre conteneur déjà montés on peut utiliser --volumes-from <container>

On peut aussi créer le volume à l'avance et l'attacher après coup à un conteneur.

Par défaut le driver de volume est local c'est-à-dire qu'un dossier est créé sur le disque de l'hôte.

$ docker volume create tmp
$ docker run -d --name conteneur_1 -v tmp:/data ubuntu bash -c "while true; do date; ls /data; sleep 1; done"
$ docker run -d --name conteneur_2 -v tmp:/data ubuntu bash -c "while true; do date; ls /data; sleep 1; done"
$ docker exec conteneur_1 touch /data/file_1
$ docker exec conteneur_2 touch /data/file_2
$ docker logs conteneur_1

Plugins de volumes

On peut utiliser d'autres systèmes de stockage en installant de nouveau plugins de driver de volume. Par exemple, le plugin vieux/sshfs permet de piloter un volume distant via SSH.

Exemples:

  • SSHFS (utilisation d'un dossier distant via SSH)
  • NFS (protocole NFS)
  • BeeGFS (système de fichier distribué générique)
  • Amazon EBS (vendor specific)
  • etc.
$ docker volume create -d vieux/sshfs -o sshcmd=<sshcmd> -o allow_other sshvolume
$ docker run -p 8080:8080 -v sshvolume:/path/to/folder --name test someimage

Permissions

  • Un volume est créé avec les permissions du dossier préexistant.
FROM debian
RUN groupadd -r graphite && useradd -r -g graphite graphite
RUN mkdir -p /data/graphite && chown -R graphite:graphite /data/graphite
VOLUME /data/graphite
USER graphite
CMD ["echo", "Data container for graphite"]

Backups de volumes

Pour effectuer un backup la méthode recommandée est d'utiliser un conteneur suplémentaire dédié

  • qui accède au volume avec --volume-from
  • qui est identique aux autres et donc normalement avec les mêmes UID/GID/permissions.

Portainer

Si vous aviez déjà créé le conteneur Portainer, vous pouvez le relancer en faisant docker start portainer, sinon créez-le comme suit :

docker volume create portainer_data
docker run --detach --name portainer \
-p 9000:9000 \
-v portainer_data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
portainer/portainer-ce
  • Remarque sur la commande précédente : pour que Portainer puisse fonctionner et contrôler Docker lui-même depuis l'intérieur du conteneur il est nécessaire de lui donner accès au socket de l'API Docker de l'hôte grâce au paramètre --volume ci-dessus.

  • Visitez ensuite la page http://localhost:9000 pour accéder à l'interface.

  • Créez votre user admin avec le formulaire.

  • Explorez l'interface de Portainer.

Facultatif : utiliser VOLUME avec microblog

  • Clonons le repo microblog ailleurs :
git clone https://github.com/uptime-formation/microblog/ --branch tp2-dockerfile microblog-volume
  • Ouvrons ça avec VSCode : codium microblog-volume

  • Lire le Dockerfile de l'application microblog.

Un volume Docker apparaît comme un dossier à l'intérieur du conteneur. Nous allons faire apparaître le volume Docker comme un dossier à l'emplacement /data sur le conteneur.

  • Pour que l'app Python soit au courant de l'emplacement de la base de données, ajoutez à votre Dockerfile une variable d'environnement DATABASE_URL ainsi (cette variable est lue par le programme Python) :
ENV DATABASE_URL=sqlite:////data/app.db

Cela indique que l'on va demander à Python d'utiliser SQLite pour stocker la base de données comme un unique fichier au format .db (SQLite) dans un dossier accessible par le conteneur. On a en fait indiqué à l'app Python que chemin de la base de données est : /data/app.db

  • Ajouter au Dockerfile une instruction VOLUME pour stocker la base de données SQLite de l'application.

Voici le Dockerfile complet :

FROM python:3.9-alpine

COPY ./requirements.txt /requirements.txt
RUN pip3 install -r requirements.txt
ENV FLASK_APP microblog.py

COPY ./ /microblog
WORKDIR /microblog

ENV CONTEXT PROD

EXPOSE 5000

ENV DATABASE_URL=sqlite:////data/app.db
VOLUME ["/data"]

CMD ["./boot.sh"]
  • Créez un volume nommé appelé microblog_db, et lancez un conteneur l'utilisant, créez un compte et écrivez un message.
  • Vérifier que le volume nommé est bien utilisé en branchant un deuxième conteneur microblog utilisant le même volume nommé.