1069 votes

Comment gérer le stockage persistant (par exemple, les bases de données) dans Docker ?

Comment gérer le stockage persistant pour vos conteneurs Docker ?

J'utilise actuellement cette approche : construire l'image, par exemple pour PostgreSQL, et ensuite démarrer le conteneur avec

docker run --volumes-from c0dbc34fd631 -d app_name/postgres

IMHO, cela a l'inconvénient, que je ne dois jamais (par accident) supprimer le conteneur "c0dbc34fd631".

Une autre idée serait de monter les volumes de l'hôte "-v" dans le conteneur, cependant, l'option Identifiant de l'utilisateur à l'intérieur du conteneur ne correspond pas nécessairement à la Identifiant de l'utilisateur de l'hôte, et les permissions pourraient être faussées.

Note : Au lieu de --volumes-from 'cryptic_id' vous pouvez également utiliser --volumes-from my-data-containermy-data-container est un nom que vous avez assigné à un conteneur de données uniquement, par ex. docker run --name my-data-container ... (voir la réponse acceptée)

0 votes

Désolé, je me suis mal exprimé, je voulais dire : toutes mes futures instances de cette image dépendent de ce conteneur. Si je supprime ce conteneur par accident, j'ai des problèmes.

0 votes

@AntonStrogonoff - ouaip, erreur de formulation - je voulais dire : Je dois m'assurer que je ne supprimerai jamais cet ancien conteneur (éventuellement), car alors la référence au stockage "persistant" disparaîtrait également.

0 votes

Il devrait l'être --name . vous avez -name

1019voto

tommasop Points 5692

Docker 1.9.0 et supérieur

Utilisez API de volume

docker volume create --name hello
docker run -d -v hello:/container/path/for/volume container_image my_command

Cela signifie que le modèle de conteneur de données uniquement doit être abandonné en faveur des nouveaux volumes.

En fait, l'API de volume n'est qu'un meilleur moyen de réaliser ce qui était le modèle de conteneur de données.

Si vous créez un conteneur avec un -v volume_name:/container/fs/path Docker créera automatiquement un volume nommé pour vous qui peut :

  1. Être répertorié par l'intermédiaire du docker volume ls
  2. Être identifié par le biais du docker volume inspect volume_name
  3. Sauvegardé comme un répertoire normal
  4. Sauvegardé comme avant à travers un --volumes-from connexion

La nouvelle API de volume ajoute une commande utile qui vous permet d'identifier les volumes pendants :

docker volume ls -f dangling=true

Et ensuite le supprimer par son nom :

docker volume rm <volume name>

Comme le souligne @mpugach dans les commentaires, vous pouvez vous débarrasser de tous les volumes pendants avec une belle ligne unique :

docker volume rm $(docker volume ls -f dangling=true -q)
# Or using 1.13.x
docker volume prune

Docker 1.8.x et inférieur

L'approche qui semble fonctionner le mieux pour la production est d'utiliser un fichier conteneur de données uniquement .

Le conteneur de données uniquement est exécuté sur une image de base et ne fait rien d'autre que d'exposer un volume de données.

Vous pouvez ensuite exécuter n'importe quel autre conteneur pour avoir accès aux volumes du conteneur de données :

docker run --volumes-from data-container some-other-container command-to-execute
  • Ici vous pouvez avoir une bonne idée de la façon dont vous devez disposer les différents récipients.
  • Ici il y a un bon aperçu de la façon dont les volumes fonctionnent.

Sur cet article de blog il y a une bonne description de ce que l'on appelle conteneur comme modèle de volume ce qui clarifie le point principal d'avoir conteneurs de données uniquement .

La documentation de Docker contient désormais la description DÉFINITIVE de la fonction conteneur en volume/s modèle.

Voici la procédure de sauvegarde/restauration pour Docker 1.8.x et inférieur.

BACKUP :

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm : retirer le conteneur lorsqu'il sort
  • --volumes-from DATA : attacher aux volumes partagés par le conteneur DATA
  • -v $(pwd):/backup : lier le montage du répertoire actuel dans le conteneur ; écrire le fichier tar dans le conteneur.
  • busybox : une petite image plus simple - bonne pour une maintenance rapide
  • tar cvf /backup/backup.tar /data : crée un fichier tar non compressé de tous les fichiers du répertoire /data

RESTORE :

# Create a new data container
$ sudo docker run -v /data -name DATA2 busybox true
# untar the backup files into the new containers data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

Voici une belle article de l'excellent Brian Goff expliquant pourquoi il est bon d'utiliser la même image pour un conteneur et un conteneur de données.

0 votes

Merci Tom pour ce partage ! J'aime beaucoup l'approche du conteneur de données uniquement - surtout avec le drapeau "-name" lors de son exécution/création.

0 votes

Cette méthode est-elle préférable à -link ? La méthode de liaison semble relativement nouvelle, mais je pense qu'elle permet de partager des données sans avoir besoin d'un conteneur de données distinct.

8 votes

C'est un outil différent pour un besoin différent. --volumes-from vous permettent de partager l'espace disque --link vous permettent de partager des services.

82voto

amitmula Points 16

Sur Version Docker v1.0 La commande suivante permet de lier le montage d'un fichier ou d'un répertoire sur la machine hôte :

$ docker run -v /host:/container ...

Le volume ci-dessus pourrait être utilisé comme un stockage persistant sur l'hôte exécutant Docker.

3 votes

C'est la réponse recommandée car elle est beaucoup moins complexe que l'approche volume-conteneur qui recueille le plus de suffrages pour le moment.

3 votes

J'aimerais qu'il y ait un drapeau pour spécifier un mappage host-uid : container-uid et host-gid : container-gid lors de l'utilisation de cette commande de montage de volume.

38voto

toast38coza Points 73

Depuis la version 1.6 de Docker Compose, la prise en charge des volumes de données est améliorée dans Docker Compose. Le fichier compose suivant créera une image de données qui persistera entre les redémarrages (ou même la suppression) des conteneurs parents :

Voici l'annonce sur le blog : Compose 1.6 : Nouveau fichier Compose pour définir les réseaux et les volumes

Voici un exemple de fichier de composition :

version: "2"

services:
  db:
    restart: on-failure:10
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
  web:
    restart: on-failure:10
    build: .
    command: gunicorn mypythonapp.wsgi:application -b :8000 --reload
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

volumes:
  db-data:

Pour autant que je puisse comprendre : Cela va créer un conteneur de volume de données ( db_data ) qui persistera entre les redémarrages.

Si tu cours : docker volume ls vous devriez voir votre volume listé :

local               mypthonapp_db-data
...

Vous pouvez obtenir plus de détails sur le volume de données :

docker volume inspect mypthonapp_db-data
[
  {
    "Name": "mypthonapp_db-data",
    "Driver": "local",
    "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data"
  }
]

Quelques tests :

# Start the containers
docker-compose up -d

# .. input some data into the database
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...

# Stop and remove the containers:
docker-compose stop
docker-compose rm -f

# Start it back up again
docker-compose up -d

# Verify the data is still there
...
(it is)

# Stop and remove with the -v (volumes) tag:

docker-compose stop
docker=compose rm -f -v

# Up again ..
docker-compose up -d

# Check the data is still there:
...
(it is).

Notes :

  • Vous pouvez également spécifier divers pilotes dans le volumes bloc. Par exemple, vous pouvez spécifier le pilote Flocker pour db_data :

    volumes:
      db-data:
        driver: flocker
  • À mesure qu'ils améliorent l'intégration entre Docker Swarm et Docker Compose (et qu'ils commencent éventuellement à intégrer Flocker dans l'écosystème Docker (j'ai entendu une rumeur selon laquelle Docker a acheté Flocker), je pense que cette approche devrait devenir de plus en plus puissante.

Avis de non-responsabilité : Cette approche est prometteuse, et je l'utilise avec succès dans un environnement de développement. J'hésiterais à l'utiliser en production pour l'instant !

0 votes

Flocker a été fermer et il n'y a pas beaucoup d'activité sur le site. répertoire Github

18voto

ben_frankly Points 1763

Au cas où la mise à jour 5 de la réponse sélectionnée ne serait pas claire, à partir de Docker 1.9, vous pouvez créer des volumes qui peuvent exister sans être associés à un conteneur spécifique, rendant ainsi obsolète le modèle du " conteneur de données uniquement ".

Voir Conteneurs de données uniquement obsolètes avec docker 1.9.0 ? #17798 .

Je pense que les responsables de la maintenance de Docker ont réalisé que le modèle de conteneur de données uniquement était un peu mal conçu et ont décidé de faire des volumes une entité distincte qui peut exister sans conteneur associé.

17voto

Czar Pino Points 1960

Lorsque vous utilisez Docker Compose pour attacher simplement un volume nommé, par exemple :

version: '2'
services:
  db:
    image: mysql:5.6
    volumes:
      - db_data:/var/lib/mysql:rw
    environment:
      MYSQL_ROOT_PASSWORD: root
volumes:
  db_data:

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X