Docker-检查postgres是否准备就绪

sup*_*r.t 5 postgresql centos docker kong

I have a Kong API Gateway container and a postgres container and I need to check whether postgres has started up and ready from the Kong container before running the migrations. I was thinking of installing the postgres client utilities into a custom image based on the official Kong image using RUN yum install postgresql -y && yum clean all in my Dockerfile and using either psql or pg_isready to achieve this. I've created a postgres user called polling with an empty password specifically for checking the status of the server by these two utilities. Neither of them work.

I tried to execute these commands from the custom Kong image:

  1. psql。该命令psql -h postgres -U polling -w -c '\l'失败,并显示错误消息psql: fe_sendauth: no password supplied。但是用户没有密码。我究竟做错了什么?此处描述使用psql检查服务器是否准备就绪的完整shell脚本。

  2. pg_isready。我不知道如何将此实用程序单独安装到基于官方Kong映像的自定义映像中,而该映像又基于该centos:7映像而postgresql打包,其中不包含pg_isready。只有这些实用程序的安装,并可以发现/usr/binpg_configpg_dumppg_dumpallpg_restorepsql。如何安装pg_isready?我不想在Kong映像中安装完整的服务器。

Mik*_*maa 31

这是一个使用pg_isreadyPostgreSQL 提供的工具的 shell one liner 。

调用外部 docker:

DOCKER_CONTAINER_NAME="mypgcontainer"
timeout 90s bash -c "until docker exec $DOCKER_CONTAINER_NAME pg_isready ; do sleep 5 ; done"
Run Code Online (Sandbox Code Playgroud)

基于 Jeroma Belleman 的帖子

  • 这是一个新的答案。 (2认同)

sup*_*r.t 7

我的解决方案是基于官方 kong 图像创建一个新图像并像这样覆盖入口点:

#!/usr/bin/env bash
set -e

# Disabling nginx daemon mode
export KONG_NGINX_DAEMON="off"

# Setting default prefix (override any existing variable)
export KONG_PREFIX="/usr/local/kong"

# Prepare Kong prefix
if [ "$1" = "/usr/local/openresty/nginx/sbin/nginx" ]; then
    kong prepare -p "/usr/local/kong"
fi

#waiting for postgres
until psql --host=$KONG_PG_HOST --username=$POLLING_USER $POLLING_DATABASE -w &>/dev/null
do
  echo "Waiting for PostgreSQL..."
  sleep 1
done

echo "Postgres is ready, running the migrations..."

kong migrations up

echo "READY TO START UP KONG USING CMD" $@;

exec "$@"
Run Code Online (Sandbox Code Playgroud)


小智 7

我试过等待它,但在 docker 容器中运行它可能是一个问题,因为在 docker 镜像中可能没有安装 nc(有时甚至没有 ping、telnet、curl ......)。因此,为了检查数据库是否已启动并正在运行,我在 docker compose 文件中使用了 HealthCheck 什么是检查 pg_isready 的返回值,什么是 postgres 数据库的一部分,因此您不需要在 docker 图像中安装任何东西:

version: '2.3'
services:
  postgres-db:
    image: postgresImage
    healthcheck:
      test: /usr/bin/pg_isready
      interval: 5s
      timeout: 10s
      retries: 120
    ports:
      - '5432:5432'

  aplication:
    image: applicationImage
    depends_on:
      postgres-db:
        condition: service_healthy
Run Code Online (Sandbox Code Playgroud)

  • @MikeBranski @davidgoli @super.t 为了增加混乱,Docker-Compose v3.9 为“depends_on”重新添加了“condition”。您现在可以通过“service_started”、“service_healthy”和“service_completed_successively”条件控制启动。 (7认同)
  • 在 compose v3 中删除了depends_on (5认同)
  • @super.t `depends_on` 在 v3 中[仍然存在](https://docs.docker.com/compose/compose-file/#depends_on)。 (2认同)
  • @MikeBranski [版本3不再支持depends_on的条件形式](https://docs.docker.com/compose/compose-file/#depends_on) (2认同)

don*_*tin 6

我们使用端口5432上的简单TCP检查来解决此问题,而无需使用任何PG工具。我们只使用wait-for-it.sh,它效果很好。在服务器实际准备好服务之前,Postgres不会打开端口,因此,这显然可以。

样本Dockerfile:https : //github.com/apim-haufe-io/wicked.kong/blob/master/Dockerfile

相应的启动脚本(对于此特定问题,只有最后一行很有趣):https : //github.com/apim-haufe-io/wicked.kong/blob/master/startup.sh

片段:

wait-for-it.sh -h $KONG_PG_HOST -p 5432 -t 30 -- kong start --run-migrations
Run Code Online (Sandbox Code Playgroud)

等待它:https : //github.com/vishnubob/wait-for-it

  • 当您第一次必须在容器中启动 postgres 时,这不起作用,因为服务器将准备就绪并尝试运行启动脚本。我对服务器的请求导致 init 脚本崩溃。 (4认同)
  • 同意@jemiloii。该端口在 Postgres 准备好运行脚本之前可用 (2认同)