Ich versuche, eine Sicherungs- und Wiederherstellungslösung für die Docker-Container zu erstellen, mit denen wir arbeiten.
Ich habe ein von mir erstelltes Docker-Basis-Image, ubuntu:base
, und möchte es nicht jedes Mal mit einer Docker-Datei neu erstellen müssen, um Dateien hinzuzufügen.
Ich möchte ein Skript erstellen, das auf dem Host-Computer ausgeführt wird und mithilfe des Docker-Images ubuntu:base
einen neuen Container erstellt. Anschließend werden Dateien in diesen Container kopiert.
Wie kann ich Dateien vom Host in den Container kopieren?
Der Befehl cp
kann zum Kopieren von Dateien verwendet werden.
Eine bestimmte Datei kann wie folgt in den Container kopiert werden:
docker cp foo.txt mycontainer:/foo.txt
Eine bestimmte Datei kann wie folgt aus dem Container kopiert werden:
docker cp mycontainer:/foo.txt foo.txt
Zur Hervorhebung ist mycontainer
ein Container ID, kein ein Bild ID.
Mehrere Dateien, die im Ordner src
enthalten sind, können in den Ordner target
kopiert werden:
docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target
Referenz: Docker CLI-Dokumente für cp
In Docker-Versionen vor 1.8 war es nur möglich, Dateien von einem Container auf den Host zu kopieren. Nicht vom Host in einen Container.
Container-Name oder kurze Container-ID abrufen:
$ docker ps
Get full container id:
$ docker inspect -f '{{.Id}}' SHORT_CONTAINER_ID-or-CONTAINER_NAME
Datei kopieren:
$ 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
oder
$ docker inspect -f '{{.Id}}' d8e703d7e303
d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5
$ Sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt
Am saubersten ist es, beim Starten des Containers ein Host-Verzeichnis im Container bereitzustellen:
{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
Das Folgende ist eine ziemlich hässliche Methode, aber es funktioniert.
docker run -i ubuntu /bin/bash -c 'cat > file' < file
Wenn Sie dies für einen laufenden Container tun müssen, können Sie docker exec (hinzugefügt in 1.3) verwenden.
Suchen Sie zuerst den Namen oder die ID des Containers:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9b7400ddd8f ubuntu:latest "/bin/bash" 2 seconds ago Up 2 seconds elated_hodgkin
Im obigen Beispiel können wir entweder b9b7400ddd8f
oder elated_hodgkin
verwenden.
Wenn Sie alles in /tmp/somefiles
auf dem Host in /var/www
im Container kopieren möchten:
$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www
Wir können dann /bin/bash
im Container ausführen und überprüfen, ob es funktioniert hat:
$ docker exec -it elated_hodgkin /bin/bash
[email protected]:/# ls /var/www
file1 file2
Die Lösung ist unten angegeben.
[email protected]:/root# <-- get the container ID
cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root
Die Datei wird direkt an den Ort kopiert, an dem sich der Container im Dateisystem befindet.
Erstellen Sie eine neue Dock-Datei und verwenden Sie das vorhandene Image als Basis.
FROM myName/myImage:latest
ADD myFile.py bin/myFile.py
Dann baue den Container:
docker build .
Eine andere Lösung zum Kopieren von Dateien in einen laufenden Container ist die Verwendung von tar:
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
Kopiert die Datei foo.sh
in /tmp
des Containers.
Bearbeiten: Reduntant -f
entfernen, dank Maarten s Kommentar.
So kopieren Sie eine Datei vom Host in den laufenden Container
docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $Host_PATH
Basierend auf Eriks Antwort und den Kommentaren von Mikl und z0r.
Normalerweise gibt es drei Arten:
Vom Container zum Host
docker cp container_id:./bar/foo.txt .
Vom Host zu einem Container
docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
Von einem Behälter zu einem Behälter mischt sich 1 und 2
docker cp container_id1:./bar/foo.txt .
docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
Mit Docker 1.8 kann docker cp
Dateien vom Host in den Container kopieren. Siehe den Docker-Blog-Beitrag Ankündigung von Docker 1.8: Content Trust, Toolbox und Updates für Registrierung und Orchestrierung.
Dies ist eine direkte Antwort auf die Frage 'Kopieren von Dateien vom Host in den Docker-Container', die in dieser Frage im Titel gestellt wurde.
Versuchen Sie docker cp
. Dies ist der einfachste Weg und funktioniert sogar auf meinem Mac. Verwendungszweck:
docker cp /root/some-file.txt some-docker-container:/root
Dadurch wird die Datei some-file.txt
im Verzeichnis /root
auf Ihrem Host-Computer in den Docker-Container some-docker-container
in das Verzeichnis /root
kopiert. Dies kommt der sicheren Kopiersyntax sehr nahe. Und wie im vorherigen Beitrag gezeigt, können Sie es auch umgekehrt verwenden. Sie kopieren also auch Dateien aus dem Container auf den Host.
Und bevor Sie diesen Beitrag downlinken, geben Sie bitte docker cp --help
ein. Das Lesen der Dokumentation kann manchmal sehr hilfreich sein ...
Wenn Ihnen dies nicht gefällt und Sie möchten, dass die Daten in Ihrem bereits erstellten und ausgeführten Container gespeichert werden, ist die Neuerstellung heute die einzige Option. Siehe auch Wie kann ich einem vorhandenen Docker-Container ein Volume hinzufügen?.
Ich habe die meisten (upvoted) Lösungen hier ausprobiert, aber im Docker 17.09 (im Jahr 2018) gibt es keinen Ordner/var/lib/docker/aufs mehr.
Dieser einfache docker cp
hat diese Aufgabe gelöst.
docker cp c:\path\to\local\file container_name:/path/to/target/dir/
Wie bekomme ich container_name?
docker ps
Es gibt einen Abschnitt NAMES
. Verwenden Sie nicht aIMAGE
.
Geben Sie den folgenden Befehl ein, um Dateien/Ordner zwischen einem Container und dem lokalen Dateisystem zu kopieren:
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
Zum Beispiel,
docker cp /home/foo container-id:/home/dir
Geben Sie den folgenden Befehl ein, um die Contianer-ID abzurufen:
docker ps
Der obige Inhalt stammt von docker.com .
Angenommen, der Container wird bereits ausgeführt, geben Sie den folgenden Befehl ein:
# cat /path/to/Host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"
Führen Sie zum Freigeben von Dateien über das freigegebene Verzeichnis den Container aus, indem Sie den folgenden Befehl eingeben:
# docker run -v /path/to/Host/dir:/path/to/container/dir ...
Hinweis: Probleme mit Berechtigungen können auftreten, wenn die Benutzer des Containers nicht mit den Benutzern des Hosts identisch sind.
In einer Docker-Umgebung befinden sich alle Container im Verzeichnis:
/var/lib/docker/aufs/required-docker-id/
Geben Sie den folgenden Befehl ein, um das Quellverzeichnis/die Quelldatei in einen beliebigen Teil des Containers zu kopieren:
Sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/
tar
und docker cp
sind eine gute Kombination zum Kopieren von allem in einem Verzeichnis.
Erstellen Sie einen Datenvolumencontainer
docker create --name dvc --volume /path/on/container cirros
So erhalten Sie die Verzeichnishierarchie
tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container
Überprüfe deine Arbeit
docker run --rm --volumes-from dvc cirros ls -al /path/on/container
Falls jemandem wie mir nicht klar ist, was mycontainer
in @ h3nrik answer bedeutet, handelt es sich tatsächlich um die Container-ID. Um eine Datei WarpSquare.mp4
in /app/example_scenes/1440p60
von einem verlassenen Docker-Container in den aktuellen Ordner zu kopieren, habe ich diese verwendet.
docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .
dabei ruft docker ps -q -l
die Container-ID der zuletzt verlassenen Instanz auf. Falls es sich nicht um einen verlassenen Container handelt, können Sie ihn mit docker container ls
oder docker ps
abrufen.
Dies ist der Befehl zum Kopieren von Daten von Docker auf Host:
docker cp container_id:file path/filename /hostpath
docker cp a13fb9c9e674:/tmp/dgController.log /tmp/
Nachfolgend finden Sie den Befehl zum Kopieren von Daten vom Host zum Docker:
docker cp a.txt ccfbeb35116b:/home/
Wenn der Host CentOS oder Fedora ist, gibt es einen Proxy NICHT in /var/lib/docker/aufs
, aber unter /proc
:
cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root
Dieser Befehl kopiert den gesamten Inhalt des Verzeichnisses data
in /
des Containers mit der ID "containerid".
Viele, die diese Frage finden, haben möglicherweise tatsächlich das Problem, Dateien in ein Docker-Image zu kopieren , während es erstellt wird (habe ich).
In diesem Fall können Sie den Befehl COPY
in dem Dockerfile
verwenden, mit dem Sie das Image erstellen.
Sie können einfach die IP-Adresse Ihres lokalen Computers mit verfolgen
ifconfig
Dann geben Sie einfach in Ihren Docker-Container ein und tippen
scp [email protected]_address:/path_to_the_file destination
In jedem Fall, wenn Sie keinen SSH-Client und -Server installiert haben, installieren Sie ihn einfach mit:
Sudo apt-get install openssh-server
Es gibt gute Antworten, aber zu spezifisch. Ich finde heraus, dass docker ps
eine gute Möglichkeit ist, die Container-ID zu ermitteln, an der Sie interessiert sind
mount | grep <id>
um zu sehen, wo das Volume gemountet ist. Das ist
/var/lib/docker/devicemapper/mnt/<id>/rootfs/
für mich kann es aber ein anderer pfad sein je nach betriebssystem und konfiguration. Kopieren Sie nun einfach die Dateien in diesen Pfad.
Die Verwendung von -v
ist nicht immer praktisch.
Der beste Weg, um Dateien in den gefundenen Container zu kopieren, ist das Mounten eines Verzeichnisses auf dem Host mit der Option -v
des Docker-Befehls run.
Ich kopiere die Datei einfach direkt von der Stelle, an der sich der Container auf dem Host befindet.
Zum Beispiel:
Finden Sie zuerst die Container-ID heraus:
[email protected]**3aed62678d54**:/home#
Nehmen wir an, die Datei befindet sich vom Host aus im Ausgangsverzeichnis:
[email protected]:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/
Zurück zum Container ...
[email protected]**3aed62678d54**:/home# ls cheering_nasa.gif
Wenn Sie Windows als Host verwenden, können Sie mit WinSCP eine Verbindung zu Docker herstellen und Dateien über die GUI übertragen.
Unter Linux funktioniert der Befehl scp
auch über das Terminal.
Container-Up-Syntax:
docker run -v /Host/folder:/Container/floder
In Docker-Datei
COPY hom* /myFolder/ # adds all files starting with "hom"
COPY hom?.txt /myFolder/ # ? is replaced with any single character, e.g., "home.txt"
Dies ist ein Onliner zum Kopieren einer einzelnen Datei, während ein Tomcat-Container ausgeführt wird.
docker run -v /PATH_TO_WAR/sample.war:/usr/local/Tomcat/webapps/myapp.war -it -p 8080:8080 Tomcat
Dies kopiert die War-Datei in das Webapps-Verzeichnis und bringt Ihre App in kürzester Zeit zum Laufen.
Normalerweise erstelle ich python Server mit diesem Befehl
python -m SimpleHTTPServer
im jeweiligen verzeichnis und dann einfach mit wget die datei an den gewünschten ort im docker übertragen. Ich weiß, es ist nicht der beste Weg, es zu tun, aber ich finde es viel einfacher.
Ich würde das Image mit einem Daemon mounten und dann ausführen, wie hier angegeben.
docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
dann
docker exec -it mntcontainer bash
Meine Lieblingsmethode:
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
oder
mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt
Ich habe gerade damit begonnen, Docker zum Kompilieren von VLC zu verwenden. Hier ist, was Sie tun können, um Dateien aus Containern hin und her zu kopieren:
su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt
Suchen Sie nach einer vertrauten Datei in diesem txt und Sie haben den Ordner, cd als root und voila! Kopieren Sie alles, was Sie wollen.
Es könnte einen Pfad geben, in dem "verschmolzen" ist. Ich schätze, Sie möchten den Pfad, in dem "diff" ist.
Auch wenn Sie den Container verlassen und wieder da sein möchten, wo Sie aufgehört haben:
docker ps -a
docker start -i containerid
Ich denke, das ist nützlich, wenn Sie mit einem Befehl wie nichts benannt haben
docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash
Sicher die Hacker Methode aber na und!
Eine andere Problemumgehung ist die Verwendung des guten alten scp
. Dies ist nützlich, wenn Sie ein Verzeichnis kopieren müssen.
Von Ihrem Host ausführen:
scp FILE_PATH_ON_YOUR_Host IP_CONTAINER:DESTINATION_PATH
scp foo.txt 172.17.0.2:foo.txt
In dem Fall, dass Sie ein Verzeichnis kopieren müssen:
scp -r DIR_PATH_ON_YOUR_Host IP_CONTAINER:DESTINATION_PATH
scp -r directory 172.17.0.2:directory
stellen Sie sicher, dass Sie auch ssh in Ihrem Container installieren.
apt-get install openssh-server
Meiner Meinung nach müssen Sie keine Dateien in das Image kopieren, sondern können GIT oder SVN für Ihre Dateien verwenden und dann ein Volume festlegen, das mit einem lokalen Ordner synchronisiert ist. Verwenden Sie beim Ausführen des Containers ein Skript, das überprüfen kann, ob Daten bereits im lokalen Ordner vorhanden sind, wenn Sie diese nicht aus dem GIT-Repository kopieren. Das macht Ihr Bild sehr leicht.
Wenn in der Docker-Datei kein Verzeichnis als Volume definiert ist, funktioniert/var/lib/docker/aufs/mnt //. Es gibt jedoch Fälle, in denen das Verzeichnis im Container als Volume definiert ist. In diesem Fall sind die Inhalte unter aufs/mnt/*/und die vom Container angezeigten Inhalte unterschiedlich.
Sie müssen den Container mit docker inspect inspizieren und dann nach Volumes suchen. Dort finden Sie eine Erwähnung für etwas wie/var/lib/docker/vfs/dir/fe940b ... (die ID). Sie müssen die Dateien hier anstatt unter aufs/mnt/* hinzufügen/ändern.
Der verwirrende Teil ist, dass die Dateien auch unter/aufs/mnt/* erscheinen. Ich habe mir eine ganze Weile am Kopf gekratzt, warum die Änderungen hier bei mir nicht funktionierten. Hoffe das hilft jemandem.
Eines habe ich versucht und es hat funktioniert
Sobald Sie Ihren Docker-Container hochfahren und eine Datei unter diesem Container erstellen; Sie können einfach von unten auf diese Datei Ihres Docker-Hosts zugreifen: -
Versuch es einmal!