我想使用 Docker 将 .sql 文件加载到 PostgreSQL 数据库中并为其提供服务。

以下命令快速返回(在数据库完全填充之前 - 这似乎在后台异步发生)。

docker run \
    --name myContainer \
    -p 5432:5432 \
    -v mySqlFile.sql:/docker-entrypoint-initdb.d/dump.sql \
    -d postgres:alpine

由于此命令将成为脚本的一部分,因此我希望该命令一直阻塞,直到使用 mySqlFile.sql 完全初始化数据库

在加载 mySqlFile.sql 时,我将如何阻止命令或其他暂停方式?

为清楚起见:我运行上述命令,然后运行以下命令:
echo "select count(*) as \"Posts imported\" from posts;" | docker exec -i myContainer psql -U postgres
 Posts imported
----------------
              0
(1 row)

等待几秒钟,我得到了这个:
echo "select count(*) as \"Posts imported\" from posts;" | docker exec -i myContainer psql -U postgres
 Posts imported
----------------
          51103
(1 row)

这是一个问题,因为我希望构建一个自动化的解决方案。我希望 docker run 命令阻塞,直到所有记录都导入到 Postgres 中。然后我让数据库处于准备好下一个命令的状态。

最佳答案

我找到了解决办法。我想你可以用这种方式。

当您运行 postgres 镜像时,ENTRYPOINT 是一个 shell。

在那个时候,如果你运行 ps aux ,你会看到 PID 1bash

但是当所有初始化完成后, postgres 就成为 exec "$@" 的主进程。那个时候 PID 1 postgres

你可以使用这个黑客。你不知道你的初始化什么时候完成。但是您可以确定,当您的初始化完成后,您的 PID 1 将是 postgres

$ docker exec -i myContainer ps -p 1 -o comm=

这将在初始化运行时返回 bash。并在一切完成后更改为 postgres

当然,你需要循环。但是通过这种方式,您可以确定初始化何时完全完成而无需任何猜测。

更新

当您使用 alpine 图像时,它具有 ps 的剪切版本。你需要在你的 alpine 镜像中安装 uncut ps。 (堆栈溢出 question )

首先运行以下命令。
$ docker exec -i myContainer apk add --no-cache procps

现在 ps -p 1 -o comm= 将工作

希望这会有所帮助

关于postgresql - 如何阻塞直到 initdb 在 Docker Postgres 容器中完成运行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48634014/

10-16 23:06