docker - 将容器修改的文件复制到新卷中
问题描述
我是 Docker 新手。
我在一个已修改的容器中有一个 SQLite 数据库,我想为新容器保留数据。
我已经尝试创建将我的容器提交到新图像中,但它似乎没有复制编辑后的文件,而且我被告知这是一种不好的做法:
docker commit 5a8f89adeead new-image
我也尝试在我的主机中复制文件和文件夹,但它在没有我的更改的情况下被复制,就像在图像中一样:
码头工人 cp 5a8f89adeead:/anope/data/. .
和
码头工人 cp 5a8f89adeead:/anope/data/anope.db anope.db
我在这里做错了什么/错过了什么?
注意:我目前没有使用 Dockerfile,而是从 docker hub 图像创建容器。
谢谢!
解决方案
您通常将这样的数据文件保存在容器外。在 SQLite 的情况下,它是一个文件,因此很容易管理。
启动容器时,将主机目录绑定挂载到容器的数据目录中。此目录中的任何内容都将隐藏图像中最初的内容。如果您在启动时自动运行数据库迁移,这也会创建 SQLite 数据库文件。
docker run -v $PWD/data:/anope/data ...
现在,数据库是主机上的一个文件,您可以随意管理它。
# Stop the original container (avoids integrity issues with the database file)
docker stop first-container; docker rm first-container
# Create two extra copies of the database file
mkdir data2 data3
cp data/anope.db data2
cp data/anope.db data3
# Launch two new containers, pointing at those data directories
docker run -v $PWD/data2:/anope/data --name second-container ...
docker run -v $PWD/data3:/anope/data --name third-container ...
除了确保应用程序代码和数据不在同一个目录中之外,您不需要在 Dockerfile 中提供任何特殊支持。
请注意,此设置根本不关心容器文件系统中的内容。我们无情地丢弃了第一个容器文件系统,并并行启动了另外两个容器。需要持久化的实际数据始终保存在容器之外。(我没有使用docker commit
, docker exec
, docker cp
, 或根本没有使用docker start
过。)
如果您确实想使用种子数据创建映像,那么编写一个 Dockerfile 会非常简单:
FROM the-same-image-you-were-running
COPY anope.db /anope/data
但是,请注意,任何类型的挂载都会隐藏映像中的数据并将其替换为已挂载的数据,特别是在 Docker 中首次使用命名卷时有一个特殊情况。另请注意,如果该目录被声明为VOLUME
(可能在基础映像中),那么您无法对该目录进行进一步更改并使它们保持不变。
推荐阅读
- node.js - 在 sudo 用户中使用 nvm 安装节点
- ubuntu - 使用 Gstreamer 与 Protobuf 版本冲突
- ios - 使用“cordova 文件传输插件”从离子应用程序下载的文件未显示在 iPhone 中
- javascript - splice call和pop call的区别
- google-tag-manager - Google 跟踪代码管理器:GA 内容实验代码未在主页上触发
- spock - 如何使用 Spock Spy?
- symfony - 在 CollectionType Admin 中获取父实体 ID
- javafx - 重新获得 javafx 焦点
- scala - 如何将嵌套 JSON 的模式存储在 Spark Scala 中的变量中
- javascript - 使用 JavaScript 创建菜单树?