J'essaie de créer une solution de sauvegarde et de restauration pour les conteneurs Docker avec lesquels nous travaillons.
J'ai l'image de base Docker que j'ai créée, ubuntu:base
, et je ne veux pas avoir à la reconstruire à chaque fois avec un fichier Docker pour y ajouter des fichiers.
Je souhaite créer un script qui s'exécute à partir de la machine hôte et crée un nouveau conteneur à l'aide de l'image ubuntu:base
Docker, puis copie les fichiers dans ce conteneur.
Comment copier des fichiers de l'hôte vers le conteneur?
La commande cp
peut être utilisée pour copier des fichiers.
Un fichier spécifique peut être copié dans le conteneur, par exemple:
docker cp foo.txt mycontainer:/foo.txt
Un fichier spécifique peut être copié à partir du conteneur comme:
docker cp mycontainer:/foo.txt foo.txt
Par exemple, mycontainer
est un conteneur ID, et non un image ID.
Plusieurs fichiers contenus dans le dossier src
peuvent être copiés dans le dossier target
en utilisant:
docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target
Référence: Docker CLI docs pour cp
Dans les versions de Docker antérieures à la version 1.8, il était uniquement possible de copier des fichiers d'un conteneur vers l'hôte. Pas de l'hôte à un conteneur.
Obtenir le nom du conteneur ou l'ID de conteneur abrégé:
$ docker ps
Obtenir l'identifiant complet du conteneur:
$ docker inspect -f '{{.Id}}' SHORT_CONTAINER_ID-or-CONTAINER_NAME
Copier un fichier:
$ Sudo cp path-file-Host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d8e703d7e303 solidleon/ssh:latest /usr/sbin/sshd -D cranky_pare
$ docker inspect -f '{{.Id}}' cranky_pare
ou
$ docker inspect -f '{{.Id}}' d8e703d7e303
d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5
$ Sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt
La méthode la plus propre consiste à monter un répertoire hôte sur le conteneur lors du démarrage du conteneur:
{Host} docker run -v /path/to/hostdir:/mnt --name my_container my_image
{Host} docker exec -it my_container bash
{container} cp /mnt/sourcefile /path/to/destfile
Ce qui suit est une manière assez laide de le faire mais cela fonctionne.
docker run -i ubuntu /bin/bash -c 'cat > file' < file
Si vous avez besoin de le faire sur un conteneur en cours d'exécution, vous pouvez utiliser docker exec (ajouté dans la version 1.3).
Tout d'abord, trouvez le nom ou l'identifiant du conteneur:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9b7400ddd8f ubuntu:latest "/bin/bash" 2 seconds ago Up 2 seconds elated_hodgkin
Dans l'exemple ci-dessus, nous pouvons utiliser b9b7400ddd8f
ou elated_hodgkin
.
Si vous voulez tout copier dans /tmp/somefiles
sur l'hôte vers /var/www
dans le conteneur:
$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www
Nous pouvons ensuite exécuter /bin/bash
dans le conteneur et vérifier qu'il fonctionne:
$ docker exec -it elated_hodgkin /bin/bash
root@b9b7400ddd8f:/# ls /var/www
file1 file2
La solution est donnée ci-dessous,
root@123abc:/root# <-- get the container ID
cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root
Le fichier doit être directement copié à l'emplacement où se trouve le conteneur sur le système de fichiers.
Créez un nouveau fichier docker et utilisez l'image existante comme base.
FROM myName/myImage:latest
ADD myFile.py bin/myFile.py
Ensuite, construisez le conteneur:
docker build .
Une autre solution pour copier des fichiers dans un conteneur en cours d'exécution consiste à utiliser tar:
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
Copie le fichier foo.sh
dans /tmp
du conteneur.
Edit: Supprimer le redondant -f
, grâce au commentaire de Maarten s.
Pour copier un fichier de l'hôte vers un conteneur en cours d'exécution
docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $Host_PATH
Basé sur réponse d'Erik et les commentaires de Mikl et z0r.
Il existe généralement trois types:
D'un conteneur à l'hôte
docker cp container_id:./bar/foo.txt .
De l'hôte à un conteneur
docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
D'un contenant à un contenant, les mélanges 1 et 2
docker cp container_id1:./bar/foo.txt .
docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
Avec Docker 1.8, docker cp
est capable de copier des fichiers de l'hôte vers le conteneur. Voir l'article de blog de Docker Annonce de Docker 1.8: approbation du contenu, boîte à outils et mises à jour du registre et de l'orchestration.
Ceci est une réponse directe à la question 'Copier des fichiers d'un hôte à un conteneur Docker' soulevée dans cette question dans le titre.
Essayez docker cp
. C'est le moyen le plus simple de le faire et fonctionne même sur mon Mac. Usage:
docker cp /root/some-file.txt some-docker-container:/root
Cela copiera le fichier some-file.txt
du répertoire /root
de votre ordinateur hôte dans le conteneur Docker nommé some-docker-container
dans le répertoire /root
. C'est très proche de la syntaxe de copie sécurisée. Et comme indiqué dans le post précédent, vous pouvez l'utiliser inversement. C'est-à-dire que vous copiez également des fichiers du conteneur vers l'hôte.
Et avant de mettre ce message en liaison descendante, entrez docker cp --help
. La lecture de la documentation peut être très utile, parfois ...
Si vous n'aimez pas cette méthode et que vous voulez des volumes de données dans votre conteneur déjà créé et en cours d'exécution, la recréation est votre seule option aujourd'hui. Voir aussi Comment puis-je ajouter un volume à un conteneur Docker existant?.
J'ai essayé la plupart des solutions (votées) ici, mais dans Docker 17.09 (en 2018), il n'y a plus de dossier/var/lib/docker/aufs.
Ce simple docker cp
a résolu cette tâche.
docker cp c:\path\to\local\file container_name:/path/to/target/dir/
Comment obtenir container_name?
docker ps
Il y a une section NAMES
. N'utilisez pas aIMAGE
.
Pour copier des fichiers/dossiers entre un conteneur et le système de fichiers local, tapez la commande suivante:
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
Par exemple,
docker cp /home/foo container-id:/home/dir
Pour obtenir l'identifiant de contianer, tapez la commande donnée:
docker ps
Le contenu ci-dessus provient de docker.com .
En supposant que le conteneur est déjà en cours d'exécution, tapez la commande donnée:
# cat /path/to/Host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"
Pour partager des fichiers à l'aide d'un répertoire partagé, exécutez le conteneur en tapant la commande suivante:
# docker run -v /path/to/Host/dir:/path/to/container/dir ...
Remarque: des problèmes d'autorisations peuvent survenir car les utilisateurs du conteneur ne sont pas les mêmes que ceux de l'hôte.
Dans un environnement de menu fixe, tous les conteneurs se trouvent dans le répertoire:
/var/lib/docker/aufs/required-docker-id/
Pour copier le répertoire/fichier source dans n’importe quelle partie du conteneur, tapez la commande suivante:
Sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/
tar
et docker cp
constituent un bon combo pour tout copier dans un répertoire.
Créer un conteneur de volume de données
docker create --name dvc --volume /path/on/container cirros
Pour préserver la hiérarchie des répertoires
tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container
Vérifie ton travail
docker run --rm --volumes-from dvc cirros ls -al /path/on/container
Dans le cas où quelqu'un comme moi ne comprend pas ce que mycontainer
dans @ h3nrik signifie, il s'agit en fait de l'identifiant du conteneur. Pour copier un fichier WarpSquare.mp4
dans /app/example_scenes/1440p60
à partir d'un conteneur de menu fixe existant dans le dossier actuel, je l'ai utilisé.
docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .
où docker ps -q -l
récupère l'ID de conteneur de la dernière instance quittée. S'il ne s'agit pas d'un conteneur fermé, vous pouvez l'obtenir par docker container ls
ou docker ps
Cette commande permet de copier des données de Docker vers l'hôte:
docker cp container_id:file path/filename /hostpath
docker cp a13fb9c9e674:/tmp/dgController.log /tmp/
La commande ci-dessous permet de copier des données d'un hôte à un menu fixe:
docker cp a.txt ccfbeb35116b:/home/
Si l'hôte est CentOS ou Fedora, il existe un proxy NON dans /var/lib/docker/aufs
, mais il se trouve sous /proc
:
cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root
Cette cmd copiera tout le contenu du répertoire data
dans /
du conteneur portant l’id "conteneurid".
Beaucoup de ceux qui trouvent cette question peuvent en fait avoir le problème de copier des fichiers dans une image Docker pendant sa création (je l’ai fait).
Dans ce cas, vous pouvez utiliser la commande COPY
dans le Dockerfile
que vous utilisez pour créer l'image.
Vous pouvez simplement suivre l’adresse IP de votre ordinateur local en utilisant
ifconfig
Ensuite, entrez simplement dans votre conteneur Docker et tapez
scp user_name@ip_address:/path_to_the_file destination
Dans tous les cas, si aucun client et serveur SSH n'est installé, installez-le simplement en utilisant:
Sudo apt-get install openssh-server
Il y a de bonnes réponses, mais trop spécifiques. Je découvre que docker ps
est un bon moyen d'obtenir l'identifiant du conteneur qui vous intéresse.
mount | grep <id>
pour voir où le volume est monté. C'est
/var/lib/docker/devicemapper/mnt/<id>/rootfs/
pour moi, mais le chemin peut être différent selon le système d'exploitation et la configuration. Maintenant, copiez simplement les fichiers dans ce chemin.
Utiliser -v
n’est pas toujours pratique.
Le meilleur moyen de copier des fichiers dans le conteneur que j'ai trouvé consiste à monter un répertoire sur l'hôte à l'aide de l'option -v
de la commande d'exécution du menu fixe.
Je copie simplement le fichier directement à partir de l'emplacement du conteneur à partir de la machine hôte.
Par exemple:
Commencez par trouver l'identifiant du conteneur:
root@**3aed62678d54**:/home#
Et puis, de l'hôte, supposons que le fichier se trouve dans le répertoire de base:
root@saasdock:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/
Retour au container ...
root@**3aed62678d54**:/home# ls cheering_nasa.gif
Si vous utilisez Windows en tant qu'hôte, vous pouvez utiliser WinSCP pour vous connecter à Docker et transférer des fichiers via l'interface graphique.
Si vous utilisez Linux, la commande scp
fonctionnera également via le terminal.
Syntaxe conteneur supérieur:
docker run -v /Host/folder:/Container/floder
Dans le fichier docker
COPY hom* /myFolder/ # adds all files starting with "hom"
COPY hom?.txt /myFolder/ # ? is replaced with any single character, e.g., "home.txt"
Ceci est un fichier en ligne permettant de copier un seul fichier lors de l'exécution d'un conteneur Tomcat.
docker run -v /PATH_TO_WAR/sample.war:/usr/local/Tomcat/webapps/myapp.war -it -p 8080:8080 Tomcat
Cela va copier le fichier war dans le répertoire webapps et faire fonctionner votre application en un rien de temps.
Je crée généralement le serveur python à l'aide de cette commande
python -m SimpleHTTPServer
dans le répertoire particulier, puis utilisez simplement wget pour transférer le fichier à l’emplacement souhaité dans le menu fixe. Je sais que ce n'est pas la meilleure façon de le faire mais je le trouve beaucoup plus facile.
Je montais puis exécutais l'image avec un démon, comme il est indiqué ici;
docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
ensuite
docker exec -it mntcontainer bash
Ma méthode préférée:
CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')
mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt
ou
mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt
Je viens tout juste de commencer à utiliser Docker pour compiler VLC. Voici ce que vous pouvez faire pour copier des fichiers d'un conteneur à un autre:
su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt
Rechercher un fichier familier dans ce txt et vous aurez le dossier, cd comme root et le tour est joué! copier tout ce que vous voulez.
Il peut y avoir un chemin avec "fusionné" dedans, je suppose que vous voulez celui avec "diff" dedans.
De plus, si vous quittez le conteneur et que vous voulez être de retour là où vous l'avez laissé:
docker ps -a
docker start -i containerid
J'imagine que c'est utile quand vous ne nommez rien avec une commande comme
docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash
Bien sûr, la méthode de piratage mais alors quoi!
Une autre solution consiste à utiliser le bon vieux scp
. Ceci est utile dans le cas où vous devez copier un répertoire.
De votre hôte hôte:
scp FILE_PATH_ON_YOUR_Host IP_CONTAINER:DESTINATION_PATH
scp foo.txt 172.17.0.2:foo.txt
Dans le cas où vous devez copier un répertoire:
scp -r DIR_PATH_ON_YOUR_Host IP_CONTAINER:DESTINATION_PATH
scp -r directory 172.17.0.2:directory
assurez-vous également d’installer ssh dans votre conteneur.
apt-get install openssh-server
À mon avis, vous ne devez pas copier de fichiers dans l'image, mais vous pouvez utiliser GIT ou SVN pour vos fichiers, puis définir un volume synchronisé avec un dossier local. Utilisez un script lors de l’exécution d’un conteneur qui peut vérifier si des données existent déjà dans un dossier local s’il n’est pas copié à partir du référentiel GIT. Cela rend votre image très légère.
Si vous n’avez pas de répertoire défini comme volume dans le fichier Docker, le fichier/var/lib/docker/aufs/mnt // fonctionnera. Mais il existe des cas où le répertoire du conteneur est défini comme un volume. Dans ce cas, le contenu sous aufs/mnt/*/et le contenu vu par le conteneur sont différents.
Vous devrez inspecter le conteneur à l'aide de docker inspecter, puis rechercher des volumes. Vous y trouverez une mention pour quelque chose comme/var/lib/docker/vfs/dir/fe940b ... (l'id). Vous devrez ajouter/modifier les fichiers ici au lieu de sous aufs/mnt/*.
La partie déroutante est que les fichiers apparaissent également sous/aufs/mnt/*. J'ai passé un bon bout de temps à me gratter la tête, pourquoi les changements survenus ici ne m'ont pas fonctionné. J'espère que ça aide quelqu'un.
Une chose que j'ai essayée et qui a fonctionné
Une fois que vous faites tourner votre conteneur Docker et si vous créez un fichier sous ce conteneur; Vous pouvez facilement accéder à ce fichier depuis l’emplacement situé en dessous de votre hôte de menu fixe: -
Essayez une fois!