将容器修改的文件复制到新卷中

Copy container modified files into new volume

我是 Docker 的新手。

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

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

docker commit 5a8f89adeead new-image

我也尝试过复制主机中的文件和文件夹,但复制时没有我做任何更改,如图所示:

docker cp 5a8f89adeead:/anope/data/. .

docker cp 5a8f89adeead:/anope/data/anope.db anope.db

我在wrong/missing这里做什么?

注意:我目前没有使用 Docker 文件,而是从 docker 中心图像创建容器。

谢谢!

您通常将此类数据文件保存在容器外。对于 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 ...

除了确保应用程序代码和数据不在同一目录中之外,您的 Docker 文件中不需要任何特殊支持即可工作。

请注意,此设置根本不关心容器文件系统中的内容。我们无情地丢弃了第一个容器文件系统,并同时启动了另外两个容器。实际需要持久化的数据总是保存在容器之外。 (我根本没有使用 docker commitdocker execdocker cpdocker start。)

如果您确实想创建一个带有种子数据的图像,那么编写一个 Docker 文件会非常简单:

FROM the-same-image-you-were-running
COPY anope.db /anope/data

但是,请注意,任何类型的挂载都会隐藏映像中的数据,并将其替换为已挂载的内容,特别是在 Docker 中第一次使用命名卷时有一个特殊情况。另请注意,如果该目录声明为 VOLUME(可能在基础映像中),则您无法对该目录进行进一步更改并保留它们。