Postgres 和 Docker 根据文件更改重新部署

Postgres and Docker redeploy on file change

我正在使用 Java/Postgres/Docker/Gradle 创建 Web 应用程序。 我的项目是这样设置的:

有一个数据库容器和一个应用程序容器。应用程序容器只是 运行 一个普通的 jar 文件。使用来自主机系统的卷添加 jar 文件。容器最初 运行s 这个 jar 并监视它的变化。如果发生变化,它会重新部署 jar,使开发人员可以立即在本地机器上看到变化。这就像 deploying/updating Tomcat 上的 war 文件。当您 'push a button' 时,实时应用程序会更新。无需停止应用程序,重建并重新运行:重建即可。

使用 Dockerhub 上的 Postgres 图像,我想做类似的事情:我想在 gradle 中 'push a button' 这将更新数据库容器监控的一些文件并拥有它重新部署。

不幸的是,我碰壁了。我最初的想法是创建一个扩展 Postgres 的 Dockerfile。它所要做的只是 运行 像往常一样的 Postgres 服务和 运行 一个脚本来寻找一些文件的变化并重新部署。

不幸的是,以下 Dockerfile 失败:

FROM postgres:9.4

WORKDIR /db
COPY monitor.py .
COPY run-pg-and-monitor.sh .

CMD ["run-pg-and-monitor.sh"]

shell 脚本有以下命令:

# Run monitor in the background
python3 monitor.py &

# Run postgres normally
postgres

不幸的是,这不适用于 Postgres。我收到错误:

db_1       | "root" execution of the PostgreSQL server is not permitted.
db_1       | The server must be started under an unprivileged user ID to prevent
db_1       | possible system security compromise.  See the documentation for
db_1       | more information on how to properly start the server.

如果我将命令设置为:

CMD ["postgres"]

这是 Postgres 容器最初所做的,错误消失了。显然,这不是我需要的 运行 monitor.py。

奇怪的是,运行没有方括号的 CMD 也会导致这个问题。

CMD postgres

运行 它在 shell 环境中也失败了:

CMD ["sh", "-c", "postgres"]

也许这与从 shell...

中 运行 宁它有关

我知道 postgres 应该是 运行 来自 postgres 用户而不是 root。我觉得奇怪的是,如果我将 CMD 设置为:

CMD ["whoami"]

我得到:

db_1       | root

所以,它已经 运行 将 postgres 作为 root 没有问题。

我的第二个想法是做一个 gradle 任务:

1) 更新触发应用程序容器重新部署的 jar

2) 运行 docker exec ... 以手动更新 运行ning 数据库容器。

这个想法的唯一问题是,在没有应用程序或数据库容器的情况下,作业显然会失败 运行ning。我将不得不添加逻辑来检查它们是否存在。这似乎不太理想。

有没有人有任何见解?是否已经存在我不是war的解决方案?

这些奇怪的原因是 postgres Dockerfile 为图像设置了它自己的 docker-entrypoint.sh script as ENTRYPOINT。所以在容器启动时 docker-entrypoint.sh 被执行,任何设置为 CMD 的东西都作为参数传递给脚本。

只有当第一个传递的参数等于 postgres(参见 here and here)时,入口脚本才会为 postgres 执行所需的初始化步骤,例如删除权限,然后最终简单地执行通过CMD.

覆盖 ENTRYPOINT 而不是 CMD,本质上是用您自己的脚本包装 docker-entrypoint.sh,应该会给您期望的行为:

# Run monitor in the background
python3 monitor.py &

# Run postgres normally
docker-entrypoint.sh "$@"