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

Copying files from host to Docker container

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

我有我创建的docker-base映像,ubuntu:base,不希望每次都用docker文件重新构建它来添加文件。

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

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


可以使用cp命令复制文件。可以复制一个特定文件,如下所示:

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

对于Emphasis,mycontainer是容器ID,而不是图像ID。

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

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

参考:用于cp的Docker CLI文档

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


  • 获取容器名称或短容器ID:

    1
    $ docker ps
  • 获取完整容器ID:

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

    1
    $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
  • 例子:

    1
    2
    3
    4
    5
    6
    7
    $ 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

    1
    2
    3
    4
    5
    $ docker inspect -f   '{{.Id}}' d8e703d7e303

    d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5

    $ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt


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

    1
    2
    3
    {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


    下面是一个相当丑陋的方法,但它是有效的。

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


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

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

    1
    2
    3
    $ 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

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

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

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


    解决方案如下:

    从船坞外壳,

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

    从主机

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

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


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

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

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

    编辑:删除reduntant -f,感谢Maartens的评论。


    很容易

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

    1
    2
    3
    FROM myName/myImage:latest

    ADD myFile.py bin/myFile.py
  • 然后构建容器:

    1
    docker build .

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

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

    根据埃里克的回答和米克尔和Z0R的评论。


    使用Docker 1.8,docker cp可以将文件从主机复制到容器。请参阅Docker博客上宣布Docker 1.8的文章:内容信任、工具箱以及注册表和编排的更新。


    这是对标题中此问题中提出的"将文件从主机复制到Docker容器"问题的直接回答。

    试试docker cp。这是最简单的方法,即使在我的Mac上也能工作。用途:

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

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

    在你下载这篇文章之前,请输入docker cp --help。阅读文档可能非常有帮助,有时…

    如果您不喜欢这种方式,并且您希望在已经创建并运行的容器中包含数据卷,那么娱乐是您今天唯一的选择。另请参见如何向现有Docker容器添加卷?.


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

    这个简单的docker cp解决了这个任务。

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

    如何获取容器名称?

    1
     docker ps

    有一个NAMES部分。不要使用AIMAGE


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

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

    例如,

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

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

    1
    docker ps

    以上内容摘自docker.com。


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

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

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

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

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


    在Docker环境中,所有容器都位于以下目录中:

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

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

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


    通常有三种类型:

  • 从容器到主机

    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和2

    1
    2
    3
    docker cp container_id1:./bar/foo.txt .

    docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
  • dev3


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

    创建数据卷容器

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

    保留目录层次结构

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

    检查你的工作

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

    如果主机是Centos或Fedora,则在/var/lib/docker/aufs中没有代理,但在/proc下:

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

    此命令将把data目录的所有内容复制到id为"containerid"的容器的/目录中。


    许多发现这个问题的人实际上可能有在创建文件时将其复制到Docker映像中的问题(我做过)。

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

    请参阅文档。


    您可以使用

    1
    ifconfig

    然后进入你的码头集装箱,输入

    1
    scp user_name@ip_address:/path_to_the_file destination

    在任何情况下,如果没有安装ssh客户机和服务器,只需使用以下方法安装:

    1
    sudo apt-get install openssh-server


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

    1
    2
    3
    docker cp container_id:file path/filename /hostpath

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

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

    1
    docker cp a.txt ccfbeb35116b:/home/

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


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

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

    其中docker ps -q -l提取最后一个退出实例的容器ID。如果不是出口集装箱,您可以通过docker container lsdocker ps获得。


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

    1
    mount | grep <id>

    查看卷的安装位置。那是

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

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

    使用-v并不总是实用的。


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

    例如:

    首先找出容器ID:

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

    然后从主机中,假设文件在主目录中:

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

    回到容器…

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

    容器向上语法:

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

    码头工人档案

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

    这是用于在运行Tomcat容器时复制单个文件的联机程序。

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

    这将把war文件复制到webapps目录,并让你的应用在短时间内运行。


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

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


    我最喜欢的方法:

    容器:

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

    TXT文件

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

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


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

    python -m SimpleHTTPServer

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


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

    您需要使用Docker Inspect检查集装箱,然后查找体积。在这里,您将看到一个关于/var/lib/docker/vfs/dir/fe940b等内容的提示…(身份证)。您需要在这里添加/修改文件,而不是在aufs/mnt/*下。

    令人困惑的是,这些文件也出现在/aufs/mnt/*下。我花了很长时间在挠头,为什么这里的变化对我不起作用。希望这能帮助别人。


    有一件事我试过了,它奏效了。

    旋转Docker容器后,如果在该容器下创建任何文件,则可以从Docker主机的以下位置轻松访问该文件:

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

    尝试一次!


    我刚开始使用Docker来编译VLC,下面是从容器中来回复制文件的方法:

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

    在那个文本文件中搜索一个熟悉的文件,你就会得到文件夹,CD作为根目录,瞧!复制你想要的。

    可能有一条路径中有"合并"的,我想您希望其中有"diff"的路径。

    另外,如果您退出容器并想回到您离开的地方:

    1
    2
    docker ps -a
    docker start -i containerid

    我想当你没有用这样的命令来命名任何东西的时候这是有用的

    1
    docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash

    当然是黑客的方法,但那又怎样呢?


    我将装载并运行带有守护进程的映像,就像这里给出的一样;

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

    然后

    1
    docker exec -it mntcontainer bash

    另一个解决方法是使用旧的好的scp。这在需要复制目录的情况下很有用。

    从主机运行:

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

    如果需要复制目录:

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

    确保也将ssh安装到容器中。

    1
    apt-get install openssh-server


    在我看来,您不必复制图像中的文件,但您可以对文件使用git或svn,然后设置与本地文件夹同步的卷。运行容器时使用一个脚本,该脚本可以检查本地文件夹中是否存在数据(如果不从Git存储库复制数据)。这让你的形象很轻。


    试试docker cp

    用途:

    1
    docker cp CONTAINER:PATH HOSTPATH

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