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 "$@"
我正在使用 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 "$@"