postgres官方docker repo为什么不在构建时启动db服务?

时间:2015-08-04 21:28:11

标签: postgresql docker

https://github.com/docker-library/postgres(github repo)和https://registry.hub.docker.com/_/postgres/(码头中心)的背景下

可以看到数据库由Entrypoint和CMD以bash脚本

启动
/docker-entrypoint.sh

ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

为更改数据库提供的另一个脚本钩是

/docker-entrypoint-initdb.d

表示数据库仅在运行时启动(可以是pqsl),当输入docker run命令时。

这会导致问题,我们无法在构建时运行数据库之前对其进行自定义,例如添加扩展并使用数据填充数据库。

当然,它可以在运行时完成。但它有利于每次运行图像时重复操作。

那么,这个设计背后的逻辑是什么,从docker或postgres的角度来看?如何在构建时添加扩展和填充数据?

2 个答案:

答案 0 :(得分:3)

如果要在构建时自定义(创建,填充数据)数据库,这意味着数据库数据将写入docker镜像文件系统本身(因为无法在构建时安装卷)。

问题在于docker镜像文件系统是一个特殊的(AUFSbtrfs等),它不能为数据密集型应用程序(如数据库)提供良好的I / O性能服务器。

因此,您希望将数据写在卷而不是docker容器文件系统上。正如您在构建时不知道运行时使用的卷是什么,并且因为无论如何在构建时安装卷都没有意义,因此没有人应该在构建时创建数据库。

此外,如果仔细查看官方PostgreSQL映像的Dockerfile,您将看到有一条VOLUME指令,该指令将数据写入卷的路径。这意味着图像的设计使得数据永远不会到达docker容器文件系统。

如果您查看其他数据库或数据密集型应用程序的其他Dockerfiles,您会发现它们都以这种方式运行。另一个原因是它被接受为good practice以使您的docker容器不可变。

如果要为映像安装其他模块,只要这些模块不依赖于将写入卷上的数据,并且只要确保为任何路径声明卷,它们就可以了。写数据。

TL;博士

应用程序代码/二进制→docker image filesystem

应用程序数据→泊坞窗量

答案 1 :(得分:1)

这是来自postgres图像(library/postgres)的泊坞窗页面:

如果您希望在从此图像派生的图像中执行其他初始化,请在*.sql or *.sh下添加/docker-entrypoint-initdb.d脚本(如有必要,请创建目录)。在入口点调用initdb以创建默认的postgres用户和数据库之后,它将运行任何*.sql个文件并获取该目录中找到的任何*.sh脚本以进行进一步初始化开始服务。

您还可以使用简单的Dockerfile扩展图像以设置区域设置。以下示例将默认语言环境设置为de_DE.utf8

FROM postgres:9.4
RUN localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8
ENV LANG de_DE.utf8

由于数据库初始化仅在容器启动时发生,因此我们可以在创建之前设置语言。

您可以像我上面粘贴的文档中显示的那样扩展图像。您还可以使用exec命令直接从主机执行容器内的任何操作。我花了一点时间才习惯它,我越来越多地继续发现它。

<强>更新

sudo docker run --name some-postgres -v ~/PATH/TO/some-postgres/data:/var/lib/postgres/data -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=test -d postgres