将文件从主机复制到Docker容器

时间:2014-04-07 08:28:56

标签: docker docker-container

我正在尝试为我们使用的Docker容器构建备份和还原解决方案。

我已创建了Docker基本映像ubuntu:base,并且不希望每次都使用Docker文件重建它以向其添加文件。

我想创建一个从主机运行的脚本,并使用ubuntu:base Docker镜像创建一个新容器,然后将文件复制到该容器中。

如何将文件从主机复制到容器?

45 个答案:

答案 0 :(得分:2059)

cp命令可用于复制文件。可以复制一个特定文件,如:

docker cp foo.txt mycontainer:/foo.txt
docker cp mycontainer:/foo.txt foo.txt

为了强调,mycontainer容器 ID, 图像 ID。

文件夹src包含的多个文件可以使用以下方式复制到target文件夹中:

docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target

参考:Docker CLI docs for cp

在1.8之前的Docker版本中,只能将文件从容器复制到主机。不是从主机到容器。

答案 1 :(得分:159)

  1. 获取容器名称或短容器ID:

    $ docker ps
    
  2. 获取完整的容器ID:

    $ docker inspect -f   '{{.Id}}'  SHORT_CONTAINER_ID-or-CONTAINER_NAME
    
  3. 复制文件:

    $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
    
  4. 实施例

    $ 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
    

    $ docker inspect -f   '{{.Id}}' d8e703d7e303
    
    d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5
    
    $ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt
    

答案 2 :(得分:125)

最干净的方法是在启动容器时在容器上安装主机目录:

{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

答案 3 :(得分:108)

以下是一种相当丑陋的方式,但它有效。

docker run -i ubuntu /bin/bash -c 'cat > file' < file

答案 4 :(得分:39)

如果你需要在正在运行的容器上执行此操作,可以使用docker exec(在1.3中添加)。

首先,找到容器的名称或ID:

$ docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                   NAMES
b9b7400ddd8f        ubuntu:latest                "/bin/bash"         2 seconds ago       Up 2 seconds                                elated_hodgkin

在上面的示例中,我们可以使用b9b7400ddd8felated_hodgkin

如果您想将主机/tmp/somefiles中的所有内容复制到容器中的/var/www

$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www

然后我们可以在容器中执行/bin/bash并验证它是否有效:

$ docker exec -it elated_hodgkin /bin/bash
root@b9b7400ddd8f:/# ls /var/www
file1  file2

答案 5 :(得分:34)

解决方案如下:

从Docker shell,

root@123abc:/root#  <-- get the container ID

来自主持人

cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root

该文件应直接复制到容器在文件系统上的位置。

答案 6 :(得分:28)

将文件复制到正在运行的容器中的另一种解决方案是使用tar:

tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x

将文件foo.sh复制到容器的/tmp

修改:删除reduntant -f,感谢Maarten的评论。

答案 7 :(得分:28)

非常简单

  1. 创建一个新的dockerfile并使用现有的图像作为基础。

    FROM myName/myImage:latest
    
    ADD myFile.py bin/myFile.py
    
  2. 然后构建容器:

    docker build .
    

答案 8 :(得分:20)

将文件从主机复制到正在运行的容器

docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH

基于Erik's answer以及Mikl&s和z0r的评论。

答案 9 :(得分:12)

这是直接回答问题&#39;将文件从主机复制到Docker容器&#39;在标题中提出这个问题。

试试docker cp。这是最简单的方法,甚至可以在我的Mac上运行。用法:

docker cp /root/some-file.txt some-docker-container:/root

这会将主机上目录some-file.txt中的文件/root复制到名为some-docker-container的Docker容器中/root。它非常接近安全复制语法。如前一篇文章所示,您可以反过来使用它。即,您还将文件从容器复制到主机。

在您下载此信息之前,请输入docker cp --help。阅读文档可能非常有用,有时候......

如果您不喜欢这种方式并且想要在已创建和运行的容器中使用数据量,那么娱乐是您今天唯一的选择。另请参阅 How can I add a volume to an existing Docker container?

答案 10 :(得分:12)

使用Docker 1.8,docker cp能够将文件从主机复制到容器。请参阅Docker博客文章 Announcing Docker 1.8: Content Trust, Toolbox, and Updates to Registry and Orchestration

答案 11 :(得分:10)

我在这里尝试了大多数(upvoted)解决方案,但是在docker 17.09(2018年)中,不再有/ var / lib / docker / aufs文件夹。

这个简单的docker cp解决了这个问题。

docker cp c:\path\to\local\file container_name:/path/to/target/dir/

如何获取container_name?

 docker ps 

有一个NAMES部分。请勿使用IMAGE

答案 12 :(得分:9)

要在容器和本地文件系统之间复制文件/文件夹,请键入命令:

docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}

例如,

docker cp /home/foo container-id:/home/dir

要获取contianer id,请键入给定的命令:

docker ps

以上内容取自docker.com

答案 13 :(得分:7)

假设容器已在运行,请键入给定的命令:

# cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"

要使用共享目录共享文件,请通过键入给定命令来运行容器:

# docker run -v /path/to/host/dir:/path/to/container/dir ...

注意:由于容器的用户与主机的用户不同,可能会出现权限问题。

答案 14 :(得分:6)

通常有三种类型:

  1. 从容器到主机

    docker cp container_id:./bar/foo.txt .
    

dev1

  1. 从主机到容器

    docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev2

  1. 从一个容器到另一个容器将1和2混合在一起

    docker cp container_id1:./bar/foo.txt .
    
    docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev3

答案 15 :(得分:6)

在docker环境中,所有容器都可以在目录中找到:

/var/lib/docker/aufs/required-docker-id/

要将源目录/文件复制到容器的任何部分,请键入给定的命令:

sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/

答案 16 :(得分:6)

Docker cp命令是一个方便的实用程序,它允许在容器和主机系统之间复制文件和文件夹。

如果要将文件从主机系统复制到容器,则应使用docker cp命令,如下所示:

docker cp host_source_path container:destination_path

首先使用docker ps命令列出正在运行的容器:

abhishek@linuxhandbook:~$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              
  PORTS               NAMES
  8353c6f43fba        775349758637        "bash"              8 seconds ago       Up 7 
  seconds                            ubu_container

您需要知道容器ID或容器名称。在我的情况下,docker容器名称为ubu_container。且容器ID为8353c6f43fba。

如果要验证文件是否已成功复制,则可以按照以下方式输入容器,然后使用常规Linux命令:

docker exec -it ubu_container bash

将文件从主机系统复制到Docker容器 使用docker cp复制类似于Linux中的copy命令。

我要复制一个名为a.py的文件到容器中的home / dir1目录中。

docker cp a.py ubu_container:/home/dir1

如果文件已成功复制,则屏幕上不会显示任何输出。如果目标路径不存在,则会显示错误:

abhishek@linuxhandbook:~$ sudo docker cp a.txt ubu_container:/home/dir2/subsub
        Error: No such container:path: ubu_container:/home/dir2

如果目标文件已经存在,它将被覆盖而不会发出任何警告。

您也可以使用容器ID代替容器名称:

docker cp a.py 8353c6f43fba:/home/dir1

答案 17 :(得分:4)

tardocker cp是复制目录中所有内容的好组合。

创建数据卷容器

docker create --name dvc --volume /path/on/container cirros

保留目录层次结构

tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container

检查你的工作

docker run --rm --volumes-from dvc cirros ls -al /path/on/container

答案 18 :(得分:3)

docker cp SRC_PATH CONTAINER_ID:DEST_PATH

例如,我要将文件xxxx / download / jenkins复制到tomcat

我开始获取容器Tomcat的ID

docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
63686740b488        tomcat              "catalina.sh run"   12 seconds ago      Up 11 seconds       0.0.0.0:8080->8080/tcp   peaceful_babbage

docker cp xxxx/download/jenkins.war  63686740b488:usr/local/tomcat/webapps/

答案 19 :(得分:3)

如果主机是CentOS或Fedora,/var/lib/docker/aufs中不存在代理,但它位于/proc下:

cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root

此cmd会将data目录的所有内容复制到容器的/,其ID为#34; containerid&#34;。

答案 20 :(得分:3)

您只需使用

跟踪本地计算机的IP地址即可
ifconfig

然后只需进入Docker容器并输入

即可
scp user_name@ip_address:/path_to_the_file destination

在任何情况下,如果您没有安装SSH客户端和服务器,只需使用以下命令安装:

sudo apt-get install openssh-server

答案 21 :(得分:3)

许多发现此问题的人实际上可能会遇到在创建文件时将文件复制到Docker图像的问题(我做过)。

在这种情况下,您可以使用COPY中用于创建图像的Dockerfile命令。

See the documentation

答案 22 :(得分:2)

有很好的答案,但太具体了。我发现docker ps是获得您感兴趣的容器ID的好方法。然后执行

mount | grep <id>

查看卷的安装位置。这是

/var/lib/docker/devicemapper/mnt/<id>/rootfs/

对我来说,但它可能是一个不同的路径,具体取决于操作系统和配置。现在只需将文件复制到该路径即可。

使用-v并不总是切实可行。

答案 23 :(得分:2)

将文件复制到我找到的容器的最佳方法是使用docker run命令的-v选项在主机上安装目录。

答案 24 :(得分:2)

如果像我这样的人不清楚@ h3nrik答案中的mycontainer是什么意思,它实际上是容器ID。要将WarpSquare.mp4中的文件/app/example_scenes/1440p60从退出的Docker容器复制到当前文件夹,我使用了这个。

docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .

其中docker ps -q -l提取上一个退出实例的容器ID。如果不是退出的容器,则可以通过docker container lsdocker ps

获取

答案 25 :(得分:2)

这是将数据从Docker复制到主机的命令:

docker cp container_id:file path/filename /hostpath

docker cp a13fb9c9e674:/tmp/dgController.log /tmp/

以下是将数据从主机复制到docker的命令:

docker cp a.txt ccfbeb35116b:/home/

答案 26 :(得分:1)

这对我有用

#Run the docker image in detached mode 
$docker run -it -d test:latest bash

$ docker ps
CONTAINER ID        IMAGE               COMMAND
a6c1ff6348f4        test:latest     "bash"

#Copy file from host to container
sudo docker cp file.txt a6c1ff6348f4:/tmp

#Copy the file from container to host
docker cp test:/tmp/file.txt /home

答案 27 :(得分:1)

如果使用Windows作为主机,您可以使用WinSCP连接到Docker并通过GUI传输文件。

如果在Linux上,scp命令也可以通过终端工作。

答案 28 :(得分:1)

这是一个在运行tomcat容器时复制单个文件的在线程序。

docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat

这会将war文件复制到webapps目录,并立即让你的应用程序运行。

答案 29 :(得分:1)

我只是直接从容器所在的位置复制文件。

例如:

首先找出容器ID:

root@**3aed62678d54**:/home#

然后从主机,假设该文件位于主目录中:

root@saasdock:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/

回到容器......

root@**3aed62678d54**:/home# ls cheering_nasa.gif

答案 30 :(得分:1)

Container Up语法:

 docker run -v /HOST/folder:/Container/floder 

在Docker文件中

COPY hom* /myFolder/        # adds all files starting with "hom"
COPY hom?.txt /myFolder/    # ? is replaced with any single character, e.g., "home.txt"

答案 31 :(得分:0)

我希望在没有 .git 文件夹等文件的容器中进行构建过程,但是当我以交互方式运行容器以调试问题时,我想要这些文件。就像 Ben Davis 的回答一样,这会在容器内执行文件副本。但是我不想在进入容器时自己实际运行该命令。因此,以下脚本将起作用:

# mount the current [project] directory as read only
docker run --name my_container -v $(pwd):/mnt/application:ro -itd my_image /bin/bash
# copy the missing project files from the mounted directory
docker exec -it my_container /bin/bash -c 'cp -rnT /mnt/application $HOME/application'
# interactively use the container
docker attach my_container

这留下了一个 my_container 容器实例。要再次运行该命令,您必须编写 docker rm my_container。或者,如果您想再次进入该容器实例,则可以执行 docker start my_container && docker attach my_container

注意 cp -n 标志,它可以防止覆盖目标中已经存在的文件。 :ro 部分不允许更改主机文件。您可以将 $(pwd) 更改为特定目录,例如 /home/user/dev/application

答案 32 :(得分:0)

如果您能够使用容器注册表,那么 appendlayer 脚本可以满足您的要求:

假设 ubuntu:base 在注册表中已经可用。

然后,您可以使用脚本在其上添加由一些本地文件组成的新图层,将整个内容另存为新图像(即 ubuntu:test)。

$ tar cvf - test.txt | python main.py <host> <repository> <old-tag> <new-tag>

无需重新构建,甚至无需将任何图像数据下载到本地计算机。

答案 33 :(得分:0)

真正的交易是:

docker volume create xdata
docker volume inspect xdata

所以你会看到它的挂载点目录。
只需将您的东西复制到那里
然后

docker run  --name=example1 --mount source=xdata,destination=/xdata -it yessa bash

其中 yessa 是图像名称

答案 34 :(得分:0)

从容器复制到主机目录

docker cp [container-name/id]:./app/[index.js] index.js

(假设您已在dockerfile中创建了一个工作目录/ app)

从主机复制到容器

docker cp index.js [container-name/id]:./app/index.js

答案 35 :(得分:0)

最简单的方法是

  1. 找到容器ID
  2. docker cp <filename> <container-id>:<path>

答案 36 :(得分:0)

我刚刚开始使用docker来编译VLC,这是您可以从容器来回复制文件的操作:

roll(FromMinAndMax()
  ..min = 0
  ..max = 100
);

roll(FromList()
  ..pair = [0, 200]
);

在该txt中搜索一个熟悉的文件,您将拥有该文件夹,并以cd和root的身份访问cd!复制所有想要的内容。

可能其中包含“合并”的路径,我想您想要其中包含“ diff”的路径。

另外,如果您退出容器并想回到上次停站的地方,

su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt

我想当您未使用

这样的命令命名任何内容时,这很有用
docker ps -a
docker start -i containerid

当然可以使用黑客方法!

答案 37 :(得分:0)

如果在Dockerfile中没有将目录定义为卷,则/ var / lib / docker / aufs / mnt //将起作用。但是有时容器中的目录被定义为卷。在这种情况下,aufs / mnt / * /下的内容和容器看到的内容是不同的。

您需要使用docker inspect检查容器,然后查找卷。你可以在那里找到类似/ var / lib / docker / vfs / dir / fe940b ...(id)的内容。您需要在此处添加/修改文件,而不是在aufs / mnt /*.

令人困惑的部分是文件也出现在/ aufs / mnt / *下。我花了很长时间挠挠脑袋为什么这里的变化对我不起作用。希望这有助于某人。

答案 38 :(得分:0)

在我看来,您不必复制图像中的文件,但可以使用GIT或SVN作为文件,然后设置与本地文件夹同步的卷。在运行容器时使用脚本,该容器可以检查本地文件夹中是否已存在数据,如果不从GIT存储库复制它。这使你的图像非常轻量级。

答案 39 :(得分:0)

我通常使用此命令创建python服务器

  

python -m SimpleHTTPServer

在特定目录中,然后使用wget在docker中的所需位置传输文件。我知道这不是最好的方法,但我发现它更容易。

答案 40 :(得分:0)

我尝试过的一件事,它起作用了

启动Docker容器并在该容器下创建任何文件后;您可以从docker主机的以下位置轻松访问该文件: -

cd / var / lib / docker / aufs / containers / container_id / tmp

尝试一次!

答案 41 :(得分:0)

另一种解决方法是使用旧的scp。这在您需要复制目录的情况下非常有用。

从您的主机运行:

scp FILE_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp foo.txt 172.17.0.2:foo.txt

如果您需要复制目录:

scp -r DIR_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp -r directory 172.17.0.2:directory

一定要将ssh安装到容器中。

apt-get install openssh-server

答案 42 :(得分:0)

我最喜欢的方法:

容器:

CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')

file.txt的

mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt

mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt

答案 43 :(得分:0)

我会挂载然后用守护进程运行映像,就像这里给出的那样;

docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

然后

docker exec -it mntcontainer bash

答案 44 :(得分:-4)

尝试docker cp

用法:

docker cp CONTAINER:PATH HOSTPATH

它将文件/文件夹从PATH复制到HOSTPATH