gpt4 book ai didi

docker-compose - docker-compose 配置如何在维护现有数据的同时从使用匿名卷过渡到命名卷?

转载 作者:行者123 更新时间:2023-12-04 03:47:47 24 4
gpt4 key购买 nike

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

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

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

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

对于那些对我们选择使用容器化数据库感到疑惑的人的旁注:我们也有一个路径供用户指定外部数据库服务器(例如 RDS),但这只有我们资源最丰富的用户才能访问。

编辑:Here是一个类似的 ServerFault 问题。

最佳答案

鉴于您使用的是 official PostgreSQL image , 你可以利用他们的数据库初始化系统

If you would like to do additional initialization in an image derived from this one, add one or more *.sql, *.sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d (creating the directory if necessary). After the entrypoint calls initdb to create the default postgres user and database, it will run any *.sql files, run any executable *.sh scripts, and source any non-executable *.sh scripts found in that directory to do further initialization before starting the service.

随着 PGDATA 的改变

This optional variable can be used to define another location - like a subdirectory - for the database files. The default is /var/lib/postgresql/data. If the data volume you're using is a filesystem mountpoint (like with GCE persistent disks) or remote folder that cannot be chowned to the postgres user (like some NFS mounts), Postgres initdb recommends a subdirectory be created to contain the data.

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

我已经准备了一个示例供您测试。首先,在匿名卷上创建一个数据库,其中包含一些示例数据:

docker-compose.yml:

version: "3.7"
services:
postgres:
image: postgres
environment:
POSTGRES_PASSWORD: test
volumes:
- ./test.sh:/docker-entrypoint-initdb.d/test.sh

测试.sh:

#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "postgres" --dbname "postgres" <<-EOSQL
CREATE TABLE public.test_table (test_column integer NOT NULL);
INSERT INTO public.test_table VALUES (1);
INSERT INTO public.test_table VALUES (2);
INSERT INTO public.test_table VALUES (3);
INSERT INTO public.test_table VALUES (4);
INSERT INTO public.test_table VALUES (5);
EOSQL

注意这个test.sh是如何挂载的,它应该在/docker-entrypoint-initdb.d/目录下,以便在初始化阶段执行。上下移动堆栈以使用此示例数据初始化数据库。

现在创建一个脚本来移动数据:

move.sh:

#!/bin/bash
set -e

rm -rf $PGDATA/*
mv /var/lib/postgresql/data/* "$PGDATA/"

并使用命名卷和自定义数据位置更新 docker-compose.yml:

docker-compose.yml:

version: "3.7"
services:
postgres:
image: postgres
environment:
POSTGRES_PASSWORD: test
# set a different location for data
PGDATA: /pgdata
volumes:
# mount the named volume
- pgdata:/pgdata
- ./move.sh:/docker-entrypoint-initdb.d/move.sh

volumes:
# define a named volume
pgdata: {}

当你启动这个堆栈时,它不会找到数据库(因为命名卷最初是空的)并且 Postgres 将运行初始化脚本。首先,它运行自己的脚本来创建一个空数据库,然后从 /docker-entrypoint-initdb.d 目录运行自定义脚本。在此示例中,我将 move.sh 挂载到该目录中,这将删除临时数据库并将旧数据库移动到新位置。

关于docker-compose - docker-compose 配置如何在维护现有数据的同时从使用匿名卷过渡到命名卷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64885337/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com