如果要导出 Docker 容器内的 整个目录(包含所有文件及子目录),可以使用以下几种方法:
方法 1:使用 docker cp
直接复制目录到宿主机
适用场景 :容器正在运行或已停止(但未删除)。
命令格式:
bash
docker cp <容器名或ID>:<容器内目录路径> <宿主机目标路径>
示例 (导出 MySQL 容器的 /var/lib/mysql
数据目录):
bash
docker cp mysql_container:/var/lib/mysql /host/backup/mysql_data
- 说明 :
/host/backup/mysql_data
是宿主机上的目标路径(需提前创建)。- 导出后,宿主机上会得到一个完整的
mysql_data
目录,包含所有文件。
ps : 也可以将文件复制进容器内部
docker cp <宿主机文件或目录路径> <容器名或ID>:<容器内目标路径>
示例:
复制单个文件到容器的 /tmp 目录: docker cp /host/path/file.txt mycontainer:/tmp/
复制整个目录到容器的 /app/data 目录:docker cp /host/path/folder/ mycontainer:/app/data/
注意:如果目标路径以 / 结尾(如 /app/data/),Docker 会将目录内容复制到该路径下。
如果不以 / 结尾(如 /app/data),Docker 会将整个目录作为子目录复制。
方法 2:启动临时容器挂载目录并复制
适用场景 :容器已删除,但数据仍在匿名卷中。
步骤:
-
查找容器的匿名卷 :
bashdocker volume ls # 找到与容器关联的匿名卷(如 `abcd1234...`)
-
启动临时容器挂载匿名卷并复制数据 :
bashdocker run --rm -v <匿名卷名>:/source -v /host/backup:/backup alpine \ sh -c "cp -r /source /backup/mysql_data"
-
示例 :
bashdocker run --rm -v abcd1234:/var/lib/mysql -v /home/user/backup:/backup alpine \ sh -c "cp -r /var/lib/mysql /backup/mysql_data"
-
方法 3:通过 docker commit
创建镜像再导出
适用场景 :容器已停止或损坏,但文件系统仍可访问。
步骤:
-
将容器保存为新镜像 :
bashdocker commit <容器名或ID> temp_mysql_image
-
启动临时容器并导出目录 :
bashdocker run --rm -v /host/backup:/backup temp_mysql_image \ sh -c "cp -r /var/lib/mysql /backup/mysql_data"
-
清理临时镜像 :
bashdocker rmi temp_mysql_image
方法 4:直接访问 Docker 存储驱动数据(高级)
适用场景 :容器已删除且无匿名卷,但数据仍在 Docker 存储目录中(如 overlay2
)。
步骤:
-
找到容器的存储层 :
bashdocker inspect <容器名或ID> | grep "MergeDir"
- 输出类似:
"MergeDir": "/var/lib/docker/overlay2/abcd1234/merged"
- 输出类似:
-
直接复制数据 :
bashcp -r /var/lib/docker/overlay2/<容器ID>/merged/var/lib/mysql /host/backup/mysql_data
- 注意 :需 root 权限,且路径因 Docker 存储驱动而异(如
overlay2
、aufs
)。
- 注意 :需 root 权限,且路径因 Docker 存储驱动而异(如
验证导出的数据
检查宿主机上的目录结构和文件:
bash
ls -l /host/backup/mysql_data
- 如果导出的是 MySQL 数据,应能看到
.ibd
、.frm
等文件。
如何避免未来数据丢失?
-
始终挂载数据卷 :
bashdocker run -v /host/mysql_data:/var/lib/mysql mysql
-
使用命名卷 (Docker 自动管理):
bashdocker run -v mysql_data:/var/lib/mysql mysql
-
定期备份 :
bashdocker exec mysql_container sh -c 'mysqldump -u root -p$MYSQL_ROOT_PASSWORD --all-databases > /backup.sql' docker cp mysql_container:/backup.sql /host/backup.sql
总结表格
方法 | 适用场景 | 命令示例 |
---|---|---|
docker cp |
容器仍在运行或存在 | docker cp mysql:/var/lib/mysql /backup |
匿名卷挂载 | 容器已删除但卷存在 | docker run --rm -v <卷名>:/source -v /backup:/backup alpine cp -r /source /backup |
docker commit |
容器损坏但文件系统可读 | docker commit + 临时容器复制 |
直接访问存储层 | 紧急恢复(需 root 权限) | 从 /var/lib/docker/overlay2/<ID>/merged 复制数据 |
选择最适合你场景的方法,确保数据安全! 🔐