Docker compose docker如何在维护现有数据的同时完成从使用匿名卷到命名卷的配置转换?

Docker compose docker如何在维护现有数据的同时完成从使用匿名卷到命名卷的配置转换?,docker-compose,Docker Compose,是否有一种方法可以从使用所有匿名卷的docker compose配置迁移到使用命名卷的配置,而无需手动干预来维护数据(例如手动复制文件夹)?这可能需要用户在主机上运行脚本,但如果脚本未运行,则需要采取一些措施防止后续的docker compose up成功 我为用户安装在一系列基础设施上的开源服务器应用程序做出了贡献。我们的用户通常技术性不强,资源有限。我们提供了一个简单的基于docker compose的设置。持久数据位于容器化的postgres数据库中,该数据库将其数据存储在匿名卷上。我们所

是否有一种方法可以从使用所有匿名卷的
docker compose
配置迁移到使用命名卷的配置,而无需手动干预来维护数据(例如手动复制文件夹)?
这可能需要用户在主机上运行脚本,但如果脚本未运行,则需要采取一些措施防止后续的
docker compose up
成功

我为用户安装在一系列基础设施上的开源服务器应用程序做出了贡献。我们的用户通常技术性不强,资源有限。我们提供了一个简单的基于
docker compose
的设置。持久数据位于容器化的postgres数据库中,该数据库将其数据存储在匿名卷上。我们所有的管理指示都涉及停止运行容器,但不将其卸下

这对大多数用户来说效果很好,但有些用户最终做了
docker-compose-down
,要么是因为他们有一点docker经验,要么是简单地类比
up
。当他们重新启动服务器时,会得到新的匿名卷,看起来他们的数据丢失了。我们已经提供了从这种状态恢复的说明,但这种情况经常发生,因此我们正在重新考虑配置并探索转换到命名卷的过程

我们有许多用户乐于使用匿名卷并严格遵守我们的管理说明。这些是我们技术含量最低的用户,我们希望确保他们不会受到我们对
docker compose
配置所做任何更改的负面影响。因此,我们不能“仅仅”更改
docker compose
配置以使用命名卷并提供迁移数据的脚本。用户忘记/无法运行脚本并最终认为自己丢失了所有数据的风险太高。如果我们能够以某种方式确保只有在数据迁移完成后才能成功地使用新配置恢复服务,那么这种方法就很好了

对于那些想知道我们选择使用容器化数据库的人来说,我们还有一个路径供用户指定外部数据库服务器(例如RDS),但这只有资源最丰富的用户才能访问


编辑:是一个类似的服务器故障问题。

如果您使用的是,您可以利用他们的数据库初始化系统

如果要在从此映像派生的映像中执行其他初始化,请在/docker entrypoint initdb.d下添加一个或多个*.sql、*.sql.gz或*.sh脚本(如有必要,请创建目录)。入口点调用initdb创建默认postgres用户和数据库后,它将运行任何*.sql文件,运行任何可执行的*.sh脚本,并在该目录中找到任何不可执行的*.sh脚本,以便在启动服务之前进行进一步初始化

更改
PGDATA

此可选变量可用于为数据库文件定义另一个位置(如子目录)。默认值为/var/lib/postgresql/data。如果您使用的数据卷是文件系统装入点(如GCE永久磁盘)或无法发送给postgres用户的远程文件夹(如某些NFS装入),postgres initdb建议创建一个子目录以包含数据

解决这个问题。其思想是为Postgres文件定义一个不同的位置,并在那里装载一个命名卷。新位置最初将为空,这将触发数据库初始化脚本。您可以使用它从匿名卷中移动数据,并只执行一次

我已经准备了一个例子让你们来验证一下。首先,在匿名卷上创建一个数据库,其中包含一些示例数据:

docker compose.yml

版本:“3.7”
服务:
博士后:
图片:博士后
环境:
POSTGRES_密码:test
卷数:
-./test.sh:/docker-entrypoint-initdb.d/test.sh
测试。sh

#/bin/bash
set-e

psql-v ON_ERROR_STOP=1--用户名“postgres”--dbname“postgres”您能否提供一个docker compose配置文件作为示例?@paltaa是所讨论的配置。请注意博士后的匿名坐骑。谢谢你,这里有很多好主意!我无法运行你的示例。我必须将
mv
更改为
cp
,然后是
rm-rf
,因为我跨越了不同的卷。现在我陷入了恐慌:在尝试迁移时找不到有效的检查点记录。有什么想法吗?谢谢!完全理解这只是一个例子。我希望我能在应用它的经验教训之前让它运行。引用似乎没有什么区别。如果我把
ls$PGDATA/*
放进去,我会得到
ls:cannotaccess'/PGDATA/*':没有这样的文件或目录
。因为你在glob
ls/*
中使用ls,这意味着
列出该位置的每个目录
。如果目录为空,则可能会失败并出现错误。我建议你
exec
进入容器进行调查。毕竟是引用,对不起!我没有意识到
ls
*
有这种行为。非常感谢您深思熟虑的回复,并帮助其工作。不客气。在发布更新之前,请确保在大于1GB的数据库上进行测试。