2096

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

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

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

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

4

49 回答 49

3503

cp命令可用于复制文件。

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

docker cp foo.txt container_id:/foo.txt

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

docker cp container_id:/foo.txt foo.txt

为了强调,container_id容器ID,而不是图像ID。(docker ps用于查看包含container_ids 的列表。)

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

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

参考:Docker CLI 文档cp

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

于 2015-08-12T17:25:00.957 回答
209
  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
    

例子:

$ 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
于 2014-07-17T14:01:41.070 回答
162

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

{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
于 2014-08-12T21:28:56.850 回答
125

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

docker run -i ubuntu /bin/bash -c 'cat > file' < file
于 2014-06-11T16:02:14.040 回答
65

通常有以下三种类型:

  1. 从容器到主机

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

开发者1

  1. 从主机到容器

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

    docker cp foo.txt mycontainer:/foo.txt
    

开发2

  1. 从一个容器到一个容器混合 1 和 2

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

开发者3

于 2019-03-03T15:10:33.393 回答
51

如果您需要在正在运行的容器上执行此操作,您可以使用 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
于 2015-01-24T07:38:07.347 回答
46
  1. 创建一个新的 dockerfile 并使用现有的图像作为您的基础。

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

    docker build .
    
于 2015-07-08T20:47:43.953 回答
40

解决方案如下,

从 Docker 外壳,

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

来自主持人

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

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

于 2014-06-23T17:01:33.703 回答
33

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

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

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

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

于 2015-04-21T13:50:00.283 回答
24

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

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

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

于 2015-07-01T09:09:49.223 回答
22

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

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

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

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

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

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

于 2015-09-23T13:18:23.743 回答
18

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

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

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

如何获取容器名称?

 docker ps 

有一NAMES节。不要使用IMAGE.

于 2018-01-17T21:18:54.507 回答
16

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

于 2015-08-12T17:22:12.663 回答
15

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

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

例如,

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

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

docker ps

以上内容取自docker.com

于 2016-12-01T18:56:04.970 回答
9

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

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

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

于 2014-11-12T07:55:25.270 回答
8

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

docker cp container_id:file path/filename /hostpath

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

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

docker cp a.txt ccfbeb35116b:/home/
于 2019-02-28T12:11:46.727 回答
7

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

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

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

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

于 2015-05-27T18:15:50.257 回答
7

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 中的复制命令。

我将复制一个名为 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
于 2020-02-26T11:37:57.013 回答
6

如果主机是 CentOS 或 Fedora,有一个代理不在/var/lib/docker/aufs,但它在/proc

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

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

于 2016-02-24T14:07:13.570 回答
6

容器向上语法:

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"
于 2018-07-19T10:53:01.867 回答
5

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

ifconfig

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

scp user_name@ip_address:/path_to_the_file destination

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

sudo apt-get install openssh-server
于 2015-07-31T13:36:15.560 回答
5

tar并且docker 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
于 2016-05-09T18:39:50.827 回答
5

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

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

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

于 2018-08-08T06:31:54.067 回答
5
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/
于 2020-01-03T17:08:24.007 回答
4

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

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

请参阅文档

于 2015-06-11T18:36:28.647 回答
4

这是一个用于在运行 tomcat 容器时复制单个文件的在线工具。

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

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

于 2017-10-24T12:53:05.357 回答
4
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH

目标路径必须预先存在

于 2022-02-01T05:41:04.980 回答
3

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

于 2014-07-31T21:08:23.427 回答
3

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

mount | grep <id>

查看卷的安装位置。那是

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

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

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

于 2014-11-12T12:14:25.720 回答
3

我最喜欢的方法:

容器:

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

文件.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
于 2015-01-16T02:59:07.277 回答
3

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

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

在该 txt 中搜索一个熟悉的文件,您将拥有该文件夹,以 root 身份 cd 到它,瞧!复制所有你想要的。

可能有一条带有“合并”的路径,我猜你想要一条带有“差异”的路径。

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

docker ps -a
docker start -i containerid

我想当你没有用类似的命令命名任何东西时这很有用

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

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

于 2019-04-27T02:42:05.990 回答
3

这对我有用

#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
于 2021-04-07T16:33:52.910 回答
2

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

于 2018-05-16T19:36:27.773 回答
2

我想在没有文件.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.

于 2021-05-26T21:56:17.840 回答
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
于 2014-07-09T06:57:57.270 回答
1

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

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

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

于 2014-09-28T10:40:00.003 回答
1

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

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
于 2016-01-31T23:42:44.427 回答
1

另一种解决方法是使用旧的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
于 2016-08-29T11:34:13.330 回答
1

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

如果在 Linux 上,该scp命令也可以通过终端运行。

于 2017-01-28T12:56:10.953 回答
1

我尝试过的一件事,它奏效了

一旦你启动了你的 docker 容器,如果你在那个容器下创建了任何文件;您可以从 docker 主机的以下位置轻松访问该文件:-

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

试一次!

于 2017-08-02T10:00:21.890 回答
1

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

  1. 查找容器 ID
  2. docker cp <filename> <container-id>:<path>
于 2019-12-06T09:20:10.620 回答
1

您可以使用以下命令

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

    docker cp /hostfile container_id:/to_the_place_you_want_the_file_to_be

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

    docker cp container_id:src_path to_the_place_you_want_the_file_to_be

于 2022-01-28T13:11:06.713 回答
0

试试docker cp

用法:

docker cp CONTAINER:PATH HOSTPATH

它将文件/文件夹PATHHOSTPATH.

于 2015-01-13T20:01:09.370 回答
0

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

python -m SimpleHTTPServer

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

于 2017-12-27T11:42:44.290 回答
0

从容器复制到主机目录

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

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

从主机复制到容器

docker cp index.js [container-name/id]:./app/index.js
于 2020-05-28T15:55:13.790 回答
0

真正的交易是:

docker volume create xdata
docker volume inspect xdata

所以你会看到它的安装点目录。
把你的东西复制到
那里

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

yessa图片名称在哪里

于 2021-02-15T15:58:31.747 回答
0

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

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

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

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

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

于 2021-05-20T06:56:49.363 回答
0

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

 487b00c94dd4 = Container ID
D:\demo\demo.tar= Source Url
/myfolder= Container Url

 
docker cp "D:\demo\demo.tar" 487b00c94dd4:/myfolder
于 2021-11-17T11:23:56.973 回答
0

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

有时对 shell 启动执行单独的交互式命令很麻烦。当我想将一个点文件复制到我的容器中时,我会这样做,这样我的 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"
于 2022-01-31T21:19:11.890 回答