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

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

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

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

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

1961173 次浏览

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

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

下面给出了解决方案,

从Docker shell,

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

从主机

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

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

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

例如:

首先找出容器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
  1. 获取容器名称或短容器ID:

    $ docker ps
  2. Get full container id:

    $ docker inspect -f   '\{\{.Id}}'  SHORT_CONTAINER_ID-or-CONTAINER_NAME
  3. Copy file:

    $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE

EXAMPLE:

$ 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

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

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

{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

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

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

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

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

# 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 ...

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

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

mount | grep <id>

查看音量安装在哪里。那是

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

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

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

试试docker cp

用法:

docker cp CONTAINER:PATH HOSTPATH

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

我最喜欢的方法:

容器:

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

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

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

$ docker psCONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                   NAMESb9b7400ddd8f        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/bashroot@b9b7400ddd8f:/# ls /var/wwwfile1  file2

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

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

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

编辑:删除冗余的-f,感谢Maarten的评论。

在docker环境中,所有容器都在目录中:

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

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

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

许多发现这个问题的人实际上可能会遇到将文件复制到Docker映像当它被创建的问题(我做到了)。

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

看留档

复制文件从主机到运行容器

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

基于Erik的回答以及Mikl和z0r的评论。

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

    FROM myName/myImage:latest
    ADD myFile.py bin/myFile.py
  2. Then build the container:

    docker build .

您可以使用以下命令跟踪本地计算机的IP地址

ifconfig

然后只需输入您的Docker容器并输入

scp user_name@ip_address:/path_to_the_file destination

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

sudo apt-get install openssh-server

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

cp命令可用于复制文件。

可以将一个特定文件复制到容器中,例如:

docker cp foo.txt container_id:/foo.txt

可以从容器中复制一个特定文件,例如:

docker cp container_id:/foo.txt foo.txt

为了强调,container_id容器 ID,没有图像 ID。(使用docker ps查看包含container_id的列表。)

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

docker cp src/. container_id:/targetdocker cp container_id:/src/. target

参考:#0的Docker CLI文档

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

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

尝试docker cp。这是最简单的方法,即使在我的Mac上也可以使用。用法:

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

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

在你下载这篇文章之前,请输入docker cp --help。阅读留档会很有帮助,有时…

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

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

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

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

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

这个cmd会将data目录的所有内容复制到ID为“容器ID”的容器/

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

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

从您的主机运行:

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

如果您需要复制目录:

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

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

apt-get install openssh-server

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

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

例如,

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

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

docker ps

以上内容摘自docker.com

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

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

有一件事我试过而且奏效了

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

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

试一次!

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

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

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

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

python-m SimpleHTTPServer

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

我在这里尝试了大多数(赞成的)解决方案,但在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

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

容器升级语法:

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"

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

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

其中docker ps -q -l拉起最后一个退出实例的容器ID。如果它不是退出的容器,您可以通过docker container lsdocker ps获取它

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

docker cp container_id:file path/filename /hostpath
docker cp a13fb9c9e674:/tmp/dgController.log /tmp/

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

docker cp a.txt ccfbeb35116b:/home/

通常有三种类型:

  1. 从容器到主机

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

docker cp命令也可以两种方式工作。

dev1

  1. 从主机到容器

    docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
  2. 从主机复制到容器的第二种方法:

    docker cp foo.txt mycontainer:/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

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

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

在那个txt中搜索一个熟悉的文件,你就会得到这个文件夹,cd到它的根目录,瞧!复制你想要的一切。

可能有一个路径与“合并”,我猜你想要一个与“差异”。

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

docker ps -adocker start -i containerid

我想这是有用的,当你没有命名任何命令,如

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

当然黑客的方法,但那又怎样!

实现这一目标的最简单方法是,

  1. 查找容器id
  2. docker cp <filename> <container-id>:<path>
docker cp SRC_PATH CONTAINER_ID:DEST_PATH

例如,我想复制我的文件xxxx/下载/jenkins到tomcat

我开始得到容器Tomcat的ID

docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES63686740b488        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/

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

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

docker cp host_source_path container:destination_path

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

abhishek@linuxhandbook:~$ sudo docker psCONTAINER ID        IMAGE               COMMAND             CREATED             STATUSPORTS               NAMES8353c6f43fba        775349758637        "bash"              8 seconds ago       Up 7seconds                            ubu_container

您需要知道容器ID或容器名称。在我的例子中,docker容器名称是ubu_container。容器ID是8353c6f43fba。

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

docker exec -it ubu_container bash

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

我将把一个名为a.py的文件复制到容器中的home/dir 1目录中。

docker cp a.py ubu_container:/home/dir1

如果文件成功复制,您将不会在屏幕上看到任何输出。如果目标路径不存在,您会看到错误:

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

如果目标文件已经存在,它将在没有任何警告的情况下被覆盖。

您还可以使用容器ID而不是容器名称:

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

从容器复制到主机目录

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

(假设您在dockerfile中创建了一个workdir /app)

从主机复制到容器

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

真正的交易是:

docker volume create xdatadocker volume inspect xdata

所以你看到它的山poit dir。
在那里复制你的东西
然后

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

其中yessa是图像名称

这对我很管用

#Run the docker image in detached mode$docker run -it -d test:latest bash
$ docker psCONTAINER ID        IMAGE               COMMANDa6c1ff6348f4        test:latest     "bash"
#Copy file from host to containersudo docker cp file.txt a6c1ff6348f4:/tmp
#Copy the file from container to hostdocker cp test:/tmp/file.txt /home

如果您能够使用容器注册表,附录 Python包可以满足您的要求:

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

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

$ pip install appendlayer$ tar cvf - test.txt | appendlayer <host> <repository> <old-tag> <new-tag>

所有这些都无需重建甚至将任何图像数据下载到本地计算机。

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

# mount the current [project] directory as read onlydocker run --name my_container -v $(pwd):/mnt/application:ro -itd my_image /bin/bash# copy the missing project files from the mounted directorydocker exec -it my_container /bin/bash -c 'cp -rnT /mnt/application $HOME/application'# interactively use the containerdocker 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

使用来自容器外部的以下命令,我能够将文件从我的主机复制到容器。

 487b00c94dd4 = Container IDD:\demo\demo.tar= Source Url/myfolder= Container Url
 
docker cp "D:\demo\demo.tar" 487b00c94dd4:/myfolder

您可以使用以下命令

  1. 将文件从主机复制到docker容器

    Docker cp /hostfilecontainer_id:/to_the_place_you_want_the_file_to_be

  2. 将文件从docker容器复制到主机

    Docker cpcontainer_id:src_pathto_the_place_you_want_the_file_to_be

将dotfile带入shell会话(使用bas64转义)

有时对shell启动执行单独的交互式命令很麻烦。当我想将dotfile复制到我的容器中以便我的shell将包含我的自定义时,我会这样做

docker exec -u root -it mycontainername bash -c "echo "$(cat ~/.bashrc | base64 -w 0)" | base64 --decode > /tmp/.bashrc_inside_container; bash --rcfile /tmp/.bashrc_inside_container"
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH

目标路径必须预先存在

docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH从主机复制到容器。

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH从容器复制到主机。

我强烈建议您不要将任何文件复制到任何容器,而是使用docker卷。这将允许您在主机上持久化文件。如果您不这样做,那么当需要升级docker映像/容器时(您应该在包含任何CVE的任何版本上这样做),那么您将删除刚刚上传的文件。

我SFTP到我的Docker主机(通常Linux服务器),上传文件。