首页 > 解决方案 > 将容器修改的文件复制到新卷中

问题描述

我是 Docker 新手。

我在一个已修改的容器中有一个 SQLite 数据库,我想为新容器保留数据。

我已经尝试创建将我的容器提交到新图像中,但它似乎没有复制编辑后的文件,而且我被告知这是一种不好的做法:

docker commit 5a8f89adeead new-image

我也尝试在我的主机中复制文件和文件夹,但它在没有我的更改的情况下被复制,就像在图像中一样:

码头工人 cp 5a8f89adeead:/anope/data/. .

码头工人 cp 5a8f89adeead:/anope/data/anope.db anope.db

我在这里做错了什么/错过了什么?

注意:我目前没有使用 Dockerfile,而是从 docker hub 图像创建容器。

谢谢!

标签: dockerdocker-volumedocker-container

解决方案


您通常将这样的数据文件保存在容器外。在 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(可能在基础映像中),那么您无法对该目录进行进一步更改并使它们保持不变。


推荐阅读