如何在initdb在Docker Postgres容器中运行之前阻塞?

时间:2018-02-06 01:14:55

标签: postgresql docker

我想使用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。然后我让数据库处于准备好下一个命令的状态。

2 个答案:

答案 0 :(得分:3)

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

使用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/

在wait-for-postgres.sh

#!/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

您可以在https://docs.docker.com/compose/startup-order/找到一些提示, https://hub.docker.com/_/postgres/

答案 1 :(得分:2)

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

运行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

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

<强>更新

当您使用高山图像时,它已切割ps版本。您需要在高山图像中安装未剪切的ps。 (堆栈溢出question

首先运行以下命令。

$ docker exec -i myContainer apk add --no-cache procps

现在ps -p 1 -o comm=可以使用

希望这会有所帮助