我想使用 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 1
是 bash
。
但是当所有初始化完成后, 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/