我正在尝试为我们使用的Docker容器构建一个备份和恢复解决方案。
我有一个我创建的Docker基础镜像ubuntu:base,不想每次都用Docker文件重新构建它来添加文件。
我想创建一个从主机运行的脚本,并使用ubuntu:base Docker映像创建一个新容器,然后将文件复制到该容器中。
如何将文件从主机复制到容器?
我正在尝试为我们使用的Docker容器构建一个备份和恢复解决方案。
我有一个我创建的Docker基础镜像ubuntu:base,不想每次都用Docker文件重新构建它来添加文件。
我想创建一个从主机运行的脚本,并使用ubuntu:base Docker映像创建一个新容器,然后将文件复制到该容器中。
如何将文件从主机复制到容器?
解决方案如下所示,
从Docker外壳,
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
获取容器名称或短容器id:$docker ps获取完整容器id:$docker inspect-f“{{.Id}}”SHORT_CONTAINER_Id或CONTAINER_NAME复制文件:$sudo cp路径文件host/var/lib/docker/aufs/mnt/FUL_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
or
$ docker inspect -f '{{.Id}}' d8e703d7e303
d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5
$ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt
最干净的方法是在启动容器时在容器上装载主机目录:
{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 inspect检查集装箱,然后查找体积。在那里,您可以看到类似/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并不总是实用的。
我最喜欢的方法:
容器:
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
or
mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt
如果需要在正在运行的容器上执行此操作,可以使用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
在上面的示例中,我们可以使用b9b7400ddd8f或相关联的hodgkin。
如果要将主机上/tmp/somefile中的所有内容复制到容器中的/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
将文件复制到正在运行的容器中的另一个解决方案是使用tar:
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
将文件foo.sh复制到容器的/tmp中。
编辑:删除reduntant-f,感谢Maartens的评论。
在docker环境中,所有容器都位于以下目录中:
/var/lib/docker/aufs/必需的docker id/
要将源目录/文件复制到容器的任何部分,请键入给定命令:
sudo cp-r mydir//var/lib/docker/aufs/mnt/required docker-id/mnt/
许多发现这个问题的人实际上可能会在创建Docker映像时遇到将文件复制到Docker映像中的问题(我确实这样做了)。
在这种情况下,您可以使用Dockerfile中的COPY命令来创建图像。
请参阅文档。
将文件从主机复制到正在运行的容器
docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH
根据Erik的回答以及Mikl和z0r的评论。
创建一个新的dockerfile并使用现有图像作为基础。FROM myName/myImage:最新添加myFile.py bin/myFile.py然后构建容器:码头建造。
您可以使用
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博客文章Announcing 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中包含的多个文件可以通过以下方式复制到目标文件夹中:
docker cp src/. container_id:/target
docker cp container_id:/src/. target
参考:Docker CLI docs for cp
在1.8之前的Docker版本中,只能将文件从容器复制到主机。不是从主机到容器。
这是对标题中这个问题“将文件从主机复制到Docker容器”的直接回答。
试试docker cp。这是最简单的方法,甚至可以在我的Mac上使用。用法:
docker cp /root/some-file.txt some-docker-container:/root
这会将主机上的目录/root中的文件some-file.txt复制到名为somedocker 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"
then
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将数据目录的所有内容复制到id为“contained”的容器的/。
tar和dockercp是复制目录中所有内容的好组合。
创建数据卷容器
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_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
要在容器和本地文件系统之间复制文件/文件夹,请键入以下命令:
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
例如
docker cp /home/foo container-id:/home/dir
要获取contaner id,请键入给定的命令:
docker ps
以上内容摘自docker.com。
有一件事我试过了
启动docker容器后,如果在该容器下创建任何文件;您可以从docker主机的以下位置轻松访问该文件:-
cd/var/lib/dodocker/aufs/container/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部分。不要使用aIMAGE。
在我看来,您不必复制图像中的文件,但可以对文件使用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容器ls或docker ps获取它
这是将数据从Docker复制到Host的命令:
docker cp container_id:file path/filename /hostpath
docker cp a13fb9c9e674:/tmp/dgController.log /tmp/
以下是将数据从主机复制到docker的命令:
docker cp a.txt ccfbeb35116b:/home/
通常有三种类型:
从容器到主机docker cp container_id:/bar/foo.txt。
docker cp命令也可以双向工作。
从主机到容器docker exec-i container_id sh-c“cat>/bar/foo.txt“</foo.txt文件从主机复制到容器的第二种方法:docker cp foo.txt mycontainer:/foo.txt
从一个容器到一个容器混合1和2docker cp container_id1:/bar/foo.txt。docker exec-i container_id2 sh-c“cat>/bar/foo.txt“</foo.txt文件
我刚刚开始使用docker来编译VLC,下面是您可以从容器来回复制文件的方法:
su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt
在这个txt中搜索一个熟悉的文件,你会得到文件夹,cd作为根目录,瞧!复制所有你想要的。
可能有一个包含“merged”的路径,我猜你想要的是包含“diff”的路径。
此外,如果您退出容器并想回到之前的位置:
docker ps -a
docker start -i containerid
我想这很有用,因为你没有用这样的命令命名任何东西
docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash
当然是黑客的方法,但那又怎么样!
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/
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中的复制命令。
我要将一个名为.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
从容器复制到主机目录
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 xdata
docker volume inspect xdata
所以你可以看到它的装载点。把你的东西复制到那里然后
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 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
如果您能够使用容器注册表,appendlayer 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 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_containr。
请注意cp-n标志,如果目标中已经存在文件,它将防止覆盖这些文件。:ro部分不允许更改主机文件。您可以将$(pwd)更改为特定目录,如/home/user/dev/application。
在容器外部使用以下命令,我可以将文件从主机复制到容器。
487b00c94dd4 = Container ID
D:\demo\demo.tar= Source Url
/myfolder= Container Url
docker cp "D:\demo\demo.tar" 487b00c94dd4:/myfolder
您可以使用以下命令
将文件从主机复制到docker容器docker cp/主机文件container_id:/to_the_place_you_want_the_file_to_be将文件从docker容器复制到主机docker cp container_id:src_path to_the_place_you_want_the_file_to_be
将点文件放入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"
docker cp[OPTIONS]SRC_PATH CONTAINER:DEST_PATH从主机复制到容器。
docker cp[OPTIONS]CONTAINER:SRC_PATH DEST_PATH将从容器复制到主机。
我强烈建议您不要将任何文件复制到任何容器,而是使用docker卷。这将允许您在主机上保存文件。如果您不这样做,那么当您需要升级docker映像/容器时(您应该在包含任何CVE的任何版本上执行此操作),您将删除刚刚上传的文件。
我SFTP到Docker主机(通常是Linux服务器),在那里上传文件。