![](/img/trans.png)
[英]Initialize PostgreSQL Container with docker-entrypoint-initdb.d script
[英]flyway unable to connect to postgres container within docker-entrypoint-initdb.d script
我正在嘗試將postgres Docker映像擴展為可能(通過環境變量標志)在 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
但是,當使用RUN_MIGRATIONS=true
運行容器時, RUN_MIGRATIONS=true
無法連接到 postgres:
docker build . -t postgres-flyway && docker run -e DB_NAME=db -e RUN_MIGRATIONS=true -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres postgres-flyway
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
Success. You can now start the database server using:
pg_ctl -D /var/lib/postgresql/data -l logfile start
waiting for server to start....LOG: database system was shut down at 2018-08-06 02:19:32 UTC
LOG: MultiXact member wraparound protections are now enabled
LOG: autovacuum launcher started
LOG: database system is ready to accept connections
done
server started
ALTER ROLE
/usr/local/bin/docker-entrypoint.sh: sourcing /docker-entrypoint-initdb.d/init_db.sh
CREATE DATABASE
running migrations ...
Flyway 4.2.0 by Boxfuse
ERROR:
Unable to obtain Jdbc connection from DataSource (jdbc:postgresql://localhost:5432/db) for user 'postgres': Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL State : 08001
Error Code : 0
Message : Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
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:10.5 圖像為我的數據庫創建 docker 圖像時,我在運行 flyway 時遇到了同樣的問題。 在運行 flyway 之前,我將以下內容添加到我的 entrypoint.sh 中,以確認我看到的問題是由 @Nick Maraston 在他的回答中發布的 docker-entrypoint.sh 更改引起的:
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
與其像這樣重新啟動數據庫,更-socketFactory
解決方案是使用此處解釋的 JDBC -socketFactory
選項。
我在挖掘圖像入口點腳本時發現了這個問題。 最近對圖像的更改將 postgres 限制為僅在內部初始化期間通過 unix 域套接字偵聽連接: https : //github.com/docker-library/postgres/pull/440
確實,postgres docker 正在偵聽 unix 套接字,例如。 /var/run/postgresql/.s.PGSQL.5432
。 但是沒有必要強制服務器切換它的監聽地址。 Postgres 數據庫 URI 允許連接字符串指向 unix 套接字。
參考: 使用 SQLAlchemy 通過 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"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.