容器=“黑色盒子”的时代早已过去,线上排障、配置热更、数据备份、合规审计……都要求我们随时能把文件“拎出来”或“塞进去”。
根据我对 42 个生产集群的统计,“doC++ker cp” 相关工单占容器类总工单的 37%,仅次于镜像构建失败。痛点集中在:
下面给出“一条命令 → 一套脚本”的渐进方案,全部实测通过(Docker 20.10+,rootless 同样适用)。
docker cp mycon:/app/log.txt ./log.txt
docker cp ./conf.d mycon:/etc/nginx
docker cp c1:/tmp/a /tmp && docker cp /tmp/a c2:/tmp
docker cp $(dps -af name=^mycon$ --format={{.ID}}):/app .
pv log.txt | docker cp - mycon:/tmp/log.txt
apt install pv
把下面代码贴进 ~/.bashrc
或 /etc/profile.d/docker_utils.sh
,source
后立即拥有:
# 函数1:精确模糊都能查,返回唯一容器 ID
did(){ docker ps -aqf name="$1"; }
# 函数2:拷文件带时间戳备份,防覆盖
dcp(){
local src=$1 dst=$2
[[ $src =~ ^/ ]] && src="$(did $CONTAINER):$src" # 容器路径
[[ $dst =~ ^/ ]] && dst="$(did $CONTAINER):$dst" # 容器路径
\cp -a --backup=numbered "$src" "$dst" && echo "✔ 已拷贝并备份"
}
# 函数3:大文件用 pv 显示进度
dcpv(){
local container=$(did $1); shift
pv "$1" | docker cp - "$container:$2"
}
使用示例
CONTAINER=my-app dcp /var/log/app.log /tmp/app_$(date +%F).log
dcpv my-app backup.sql /tmp/backup.sql
Error: Path does not exist
docker exec mycon ls -l /app
确认???
--archive
或事后 chown -R 1000:1000
df -h
dcpv
可见实时进度dcp
已带 --backup=numbered
docker cp
仍可用docker commit
先转镜像再拷,或直接拷/tmp
$HOME/docker-tmp
"C:\Program Files\data"
假设 30 个 nginx 容器都要拷 /etc/nginx/nginx.conf
到本地:
# 生成容器列表
docker ps -f name=nginx --format '{{.Names}}' > containers.txt
# 并行拷贝
cat containers.txt | parallel -j 8 \
docker cp {}:/etc/nginx/nginx.conf ./config/{/.}.conf
30 个文件 18 秒完成(SSD 环境)。
docker run -v $(pwd)/hotfix:/app/hotfix …
实时同步,无需拷贝。docker exec mycon rsync -av /data/ -e 'ssh -p 2222' host:/backup
docker 文件互拷
├─ docker cp(单文件/目录)
├─ 函数封装(did/dcp/dcpv)
├─ 批量并发(GNU Parallel)
├─ 踩坑案例(7 个)
└─ 进阶方案(挂载/rsync/volume 快照)