如何在入口点等待postgres的启动?

ENTRYPOINT之前,等待postgres在我的ENTRYPOINT内完全启动的最佳方法是什么?

现在我已经在我的机器上启动了大约50秒的时间。 所以我只睡了60秒 这不太好,因为在另一台机器上运行时,这可能不起作用。

 ENTRYPOINT \ runuser -l postgres -c '/usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main -c config_file=/etc/postgresql/9.3/main/postgresql.conf & ' && \ sleep 60 && \ nosetests --verbose --cover-erase --with-coverage --cover-package=stalker 

这是启动postgres的输出:

 2017-02-13 13:46:49.541 UTC [9] LOG: database system was interrupted; last known up at 2017-02-13 12:53:23 UTC 2017-02-13 13:47:37.951 UTC [9] LOG: database system was not properly shut down; automatic recovery in progress 2017-02-13 13:47:37.994 UTC [9] LOG: redo starts at 0/1783EA0 2017-02-13 13:47:37.995 UTC [9] LOG: record with zero length at 0/17841E8 2017-02-13 13:47:37.995 UTC [9] LOG: redo done at 0/17841B8 2017-02-13 13:47:37.995 UTC [9] LOG: last completed transaction was at log time 2017-02-13 12:53:23.731984+00 2017-02-13 13:47:38.384 UTC [9] LOG: MultiXact member wraparound protections are now enabled 2017-02-13 13:47:38.387 UTC [7] LOG: database system is ready to accept connections 2017-02-13 13:47:38.387 UTC [13] LOG: autovacuum launcher started 

请,我明白,这违背了在ENTRYPOINT运行多个命令的ENTRYPOINT 。 在这种情况下,我有很好的理由去做这件事。

感谢@zeppelinbuild议pg_isready 。 我结束了使用这个:

 #!/bin/bash # wait-for-postgres.sh set -e cmd="$@" timer="5" until runuser -l postgres -c 'pg_isready' 2>/dev/null; do >&2 echo "Postgres is unavailable - sleeping for $timer seconds" sleep $timer done >&2 echo "Postgres is up - executing command" exec $cmd 

我在我的ENTRYPOINT使用这个:

 ENTRYPOINT \ # Start PostgreSQL runuser -l postgres -c '/usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main -c config_file=/etc/postgresql/9.3/main/postgresql.conf & ' && \ # Exectute tests when db is up ./wait-for-postgres.sh nosetests --verbose --cover-erase --with-coverage --cover-package=stalker 

我通常会使用一个小的“tcp-port-wait”脚本,如下所示:

 #!/bin/bash set -e if [ -z "$1" -o -z "$2" ] then echo "tcp-port-wait - block until specified TCP port becomes available" echo "Usage: ntcp-port-wait HOST PORT" exit 1 fi echo Waiting for port $1:$2 to become available... while ! nc -z $1 $2 2>/dev/null do let elapsed=elapsed+1 if [ "$elapsed" -gt 90 ] then echo "TIMED OUT !" exit 1 fi sleep 1; done echo "READY !" 

等待某个服务启动并准备就绪。

在Postgresql的情况下,它会监听的默认端口是5432 ,所以命令是:

 tcp-port-wait localhost 5432 

这将阻塞,直到Postgresql服务准备好为容器内的回送接口(在ENTRYPOINT脚本的上下文中运行)上的5432上提供连接。

你一定要把这个脚本复制到你的容器中,在Dockerfile中添加这样的一行

 COPY tcp-port-wait /usr/local/bin/ 

然后才能使用它。

并且还安装netcat实用程序。

您也可以将其用于其他types的服务,如Tomcat或Mysql。

而且,如果你需要的话,你也可以等待“外面的容器”,就像这样:

 docker exec my_container tcp-port-wait localhost 5432 

请注意,还有其他方法可以做到这一点,例如使用一些编排工具,如docker-compose with healthcheck指令 ,或者容器内部的一些进程pipe理器。

不要在一个容器中运行多个东西总是更好。 最好的方法是让你的postgres运行在一个容器中,另一个用于你的nosetests

你可以创build一个docker-compose文件,其中nosetest依赖于数据库。