将文件从Docker容器复制到主机 技术背景 在使用Docker进行开发和部署时,经常需要在容器和主机之间复制文件。例如,将容器内生成的日志文件、配置文件或构建产物复制到主机上进行查看、备份或进一步处理。
实现步骤 使用 docker cp
命令 可以使用 docker cp
命令将文件从容器复制到主机,基本语法如下:
1 docker cp <containerId>:/file/path/within/container /host/path/target
示例:
1 sudo docker cp goofy_roentgen:/out_read.jpg .
其中 goofy_roentgen
是容器名称,可以通过 sudo docker ps
命令获取。也可以使用容器ID的一部分,例如:
1 sudo docker cp 1b4a:/out_read.jpg .
使用 docker create
命令 可以使用 docker create
命令创建一个容器,然后进行文件复制,最后删除容器,示例如下:
1 2 3 docker create --name dummy IMAGE_NAME docker cp dummy:/path/to/file /dest/to/file docker rm -f dummy
挂载卷并复制文件 1 2 3 4 5 6 mkdir artifacts docker run -i -v ${PWD} /artifacts:/artifacts ubuntu:14.04 sh << COMMANDS # ... build software here ... cp <artifact> /artifacts # ... copy more artifacts into `/artifacts` ... COMMANDS
从主机复制文件到容器 1 docker cp C:/localMachineSourceFolder/someFile.txt containerId:/containerDestinationFolder
核心代码 复制文件到主机 1 docker cp containerId:source_path destination_path
从主机复制文件到容器 1 docker cp C:/localMachineSourceFolder/someFile.txt containerId:/containerDestinationFolder
使用 docker create
复制文件 1 2 3 docker create --name dummy IMAGE_NAME docker cp dummy:/path/to/file /dest/to/file docker rm -f dummy
挂载卷复制文件 1 2 3 4 mkdir artifacts docker run -i -v ${PWD} /artifacts:/artifacts ubuntu:14.04 sh << COMMANDS cp <artifact> /artifacts COMMANDS
最佳实践 处理用户ID问题 在挂载卷复制文件时,可能会遇到用户ID不匹配的问题。可以使用调用用户的UID来解决:
1 2 3 4 5 docker run -i -v ${PWD} :/working_dir -w /working_dir -u $(id -u) \ ubuntu:14.04 sh << COMMANDS # Since $(id -u) owns /working_dir, you should be okay running commands here # and having them work. Then copy stuff into /working_dir/artifacts . COMMANDS
使用 --output
标志(Docker 19.03+) 对于BuildKit基于的构建,可以使用 --output
标志将构建结果直接输出到本地目录:
1 DOCKER_BUILDKIT=1 docker build --target artifact --output type =local ,dest=. .
常见问题 容器未运行 在使用 docker cp
命令之前,容器必须处于运行状态。可以使用以下命令启动容器:
1 2 3 4 5 docker build -t IMAGE_TAG . docker run -d IMAGE_TAG CONTAINER_ID=$(docker ps -alq) docker cp $CONTAINER_ID :/path/to/file . docker stop $CONTAINER_ID
权限问题 在复制目录时,可能会遇到权限问题。可以先将目录复制到 /tmp/
,然后再移动到目标位置:
1 2 docker cp 5f2371a7da7c:/home/euler/mfem/miniapps/navier/3dfoc /tmp/mv /tmp/3dfoc ~/Downloads/
从镜像复制文件 如果要从镜像中复制文件,可以使用以下命令:
1 docker run --rm <image> cat <source > > <local_dest>
但这种方法不会保留文件的权限和修改日期。