Postgresql flyway无法连接到docker entrypoint initdb.d脚本中的postgres容器

Postgresql flyway无法连接到docker entrypoint initdb.d脚本中的postgres容器,postgresql,docker,flyway,Postgresql,Docker,Flyway,我正在尝试扩展映像,以便(通过环境变量标志)在DB init上执行flyway DB迁移。我的Dockerfile在这里: FROM postgres:9.6 # Install curl and java (for Flyway) RUN set -x \ && apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl openjdk-

我正在尝试扩展映像,以便(通过环境变量标志)在DB init上执行flyway DB迁移。我的Dockerfile在这里:

FROM postgres:9.6

# Install curl and java (for Flyway)
RUN set -x \
    && apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates curl openjdk-8-jre 

# Install Flyway
ENV FLYWAY_VERSION 4.2.0
ENV FLYWAY_INSTALL_DIR /usr/src/flyway
ENV FLYWAY_CONF ${FLYWAY_INSTALL_DIR}/flyway-${FLYWAY_VERSION}/conf/flyway.conf
ENV FLYWAY_EXE ${FLYWAY_INSTALL_DIR}/flyway-${FLYWAY_VERSION}/flyway
RUN mkdir -p ${FLYWAY_INSTALL_DIR} && \
    curl -L https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/${FLYWAY_VERSION}/flyway-commandline-${FLYWAY_VERSION}.tar.gz | \
    tar -xzC ${FLYWAY_INSTALL_DIR} && \
    chmod +x ${FLYWAY_EXE}

# Copy migration scripts
ENV MIGRATIONS_LOCATION /flyway/migrations
COPY migrations $MIGRATIONS_LOCATION

COPY init_db.sh /docker-entrypoint-initdb.d/init_db.sh
使用我的
init_db.sh
启动脚本:

#!/bin/bash
set -e

RUN_MIGRATIONS="${RUN_MIGRATIONS:-false}"
DB_URL="jdbc:postgresql://localhost:5432/$DB_NAME"

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    CREATE DATABASE $DB_NAME;
EOSQL

if [ "$RUN_MIGRATIONS" == "true" ]; then
        echo "running migrations ..."
        ${FLYWAY_EXE} -user=$POSTGRES_USER -password=$POSTGRES_PASSWORD -url=$DB_URL -locations="filesystem:$MIGRATIONS_LOCATION" migrate
fi
postgres映像在端口5432上运行postgres(与往常一样),因此我不明白为什么flyway无法通过
localhost:5432
连接到postgres

我还注意到,在此上下文中,
pg_isready
表示postgres正在接受连接,但当将主机名指定为
localhost
127.0.0.1
时,它也无法到达postgres。也就是说,通过在我的
init_db.sh
脚本中插入一些
pg_isready
命令:

...
pg_isready
pg_isready -p 5432
pg_isready -h localhost -p 5432
...
我在postgres init上看到以下日志输出:

...
/var/run/postgresql:5432 - accepting connections
/var/run/postgresql:5432 - accepting connections
localhost:5432 - no response
...

我怀疑我已经达到了postgres的初始化上下文的限制,但我想了解为什么在初始化的这一点上无法通过
localhost/127.0.0.1:5432访问postgres。

我在挖掘图像脚本时发现了这个问题。最近对映像的更改限制postgres在内部初始化期间仅侦听unix域套接字上的连接:

在基于postgres:10.5映像为数据库创建docker映像时,我在运行flyway时遇到了相同的问题。在运行flyway之前,我在entrypoint.sh中添加了以下内容,以确认我看到的问题是由docker-entrypoint.sh change@Nick Maraston在其回答中发布的问题引起的:

echo "$(date) - waiting for database to start"
while ! pg_isready -h localhost -p 5432 -d $POSTGRES_DB
do
    echo "$(date) - waiting for database to start"
    sleep 10
done
结果是上述代码永远循环。然后,我将其替换为以下代码,以重新启动在localhost上侦听TCP/IP连接的数据库:

pg_ctl -D "$PGDATA" -m fast -w stop
pg_ctl -D "$PGDATA" \
            -o "-c listen_addresses='localhost'" \
            -w start

与其像这样重新启动数据库,一个更干净的解决方案是使用JDBC
-socketFactory
选项。

postgres docker确实在侦听unix套接字,例如
/var/run/postgresql/.s.PGSQL.5432
。但不必强制服务器切换其侦听地址。Postgres数据库URI允许连接字符串指向unix套接字

参考:

该实例提供了:

export DATABASE_URL=postgres://user:password@/dbname?host=/path/to/unix/socket
我可以省略主机,并决定在/docker entrypoint initdb.d/*.sh脚本中使用此环境变量。请注意,@符号后面没有字符串,这里也没有主机查询字符串。您可能需要根据应用程序显式定义主机

解决方案:

export DATABASE_URL="postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@/$POSTGRES_DB"
export DATABASE_URL="postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@/$POSTGRES_DB"