Postgresql 在Docker Postgres容器中运行initdb之前,如何进行阻止?

Postgresql 在Docker Postgres容器中运行initdb之前,如何进行阻止?,postgresql,docker,Postgresql,Docker,我想使用Docker将.sql文件加载到PostgreSQL数据库中并提供服务 下面的命令很快返回(在数据库完全填充之前-这似乎是在后台异步发生的) 由于该命令将是脚本的一部分,我希望该命令在数据库使用mySqlFile.sql 加载mySqlFile.sql时,如何让命令阻塞,或以其他方式暂停 为清楚起见:我运行上述命令,然后运行以下命令: echo "select count(*) as \"Posts imported\" from posts;" | docker exec -i myC

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

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

由于该命令将是脚本的一部分,我希望该命令在数据库使用
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。然后,我让数据库处于一种状态,可以执行下一个命令。

想法:创建一个自定义包装,等待在填充脚本末尾为docker插入一个表中的特定记录

使用
docker compose
可以使用自定义包装器脚本:

在docker-compose.yml中

version: "2"
services:
  app:
     build: app/
     depends_on:
       - "db"
     command: ["./wait-for-postgres.sh", "db", "yourcommand", "with", "parameters"]
  db:
    build: db/
在等待博士后

#!/bin/bash
# wait-for-postgres.sh

set -e

host="$1"
shift
cmd="$@"
#wait postgres up
until psql -h "$host" -U "postgres" -c '\q'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

#wait populate script
while ! psql -h "$host" -U "postgres" -t -c "select * from docker_ready" | egrep .
do
  sleep 1
done
>&2 echo "Postgres is populated - executing command"
exec $cmd
你可以找到一些关于,
我找到了一个解决办法。我想你可以用这种方式

运行
postgres
图像时,ENTRYPOINT是一个shell

在此期间,如果运行
ps aux
,您将看到
PID 1
bash

但当所有初始化完成后,
postgres
成为
exec“$@”
的主进程。时间
PID 1
postgres

$ docker exec -i myContainer ps -p 1 -o comm=
你可以用这个黑客。您不知道初始化何时完成。但是您可以确定,当初始化完成时,
PID 1
将是
postgres

$ docker exec -i myContainer ps -p 1 -o comm=
当初始化运行时,这将返回
bash
。完成所有操作后,将更改为
postgres

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

更新

当您使用alpine image时,它已剪切了
ps
的版本。您需要在alpine映像中安装uncut
ps
。(堆栈溢出)

首先运行以下命令

$ docker exec -i myContainer apk add --no-cache procps
现在
ps-p1-o通信=
将起作用


希望这将有助于

您的docker在装载完成后运行。然后PostgreSQL服务将自动阻止,直到执行了
/docker entrypoint initdb.d
中的所有脚本。运行bash脚本而不是psql怎么样。。。在内部休眠15秒,然后执行psql命令?谢谢@Urban48,但我不想使用sleep语句,因为我无法预测sql转储的大小。15秒可能太长了(这还行)。。。但是它可能太短了(然后我的脚本就会中断)谢谢你的回答。不幸的是,数据库在initdb阶段出现(和关闭),因此此检查无法区分initdb进程的结束。感谢您的回答。不幸的是,特定的ps命令在我的环境中不起作用。不过,我很欣赏你的解决方案的聪明,我会看看是否能以此作为出发点。是的。我错过了。你在使用阿尔卑斯山。@ChrisBeach,你现在可以检查一下吗?嘿@aerokite,你有没有一个示例,我可以如何将你的建议变成一个循环,这样我就可以暂停我的脚本,直到它返回postgres?