我正在尝试为postgres设置一个自定义的Dockerfile,在启动时运行flyway迁移。到目前为止,我已经成功地构建、安装和执行了所有内容,但是由于连接错误,我无法让flyway在启动时连接到docker容器内的postgres数据库。
在你告诉我在一个docker-compose,文件中设置它之前,我想补充的是,我这样做是为了我可以使用gitlab ci/cd中的docker映像作为一个服务容器,所以使用docker-compose不是一个选项。
这是我的文档
FROM postgres:12 AS db
WORKDIR /home
# Install wget
RUN apt-get update -y \
&& apt-get install wget -y \
&& apt-get install sudo -y \
&& apt-get install lsof
RUN usermod -aG sudo postgres
RUN bash -c 'echo "postgres ALL=(ALL:ALL) NOPASSWD: ALL" | (EDITOR="tee -a" visudo)'
# Install latest version of flyway 7
RUN wget -qO- https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/7.9.2/flyway-commandline-7.9.2-linux-x64.tar.gz | tar xvz && \
ln -s `pwd`/flyway-7.9.2/flyway /usr/local/bin
# Copy database migrations for flyway
COPY reds/migrations migrations
# Set environment variables for flyway
ENV FLYWAY_LOCATIONS="/home/migrations"
ENV FLYWAY_SCHEMAS="reds"
ENV FLYWAY_CONNECT_RETRIES=5
ENV FLYWAY_BASELINE_ON_MIGRATE=false
ENV FLYWAY_OUT_OF_ORDER=false
# Make postgres startup script run flyway migrations
COPY reds/init.sh /docker-entrypoint-initdb.d/init.sh
RUN chmod +x /docker-entrypoint-initdb.d/init.sh && \
chown -R postgres /docker-entrypoint-initdb.d
EXPOSE 5432
CMD ["postgres"]
下面是在container启动时执行的脚本
#!/bin/bash
set -eou pipefail
# I've tried localhost, 0.0.0.0 and 127.0.0.1
host="$(hostname -i)"
sudo flyway migrate \
-url="jdbc:postgresql://$host:5432/$POSTGRES_DB" \
-schemas="$FLYWAY_SCHEMAS" \
-locations="$FLYWAY_LOCATIONS" \
-connectRetries="$FLYWAY_CONNECT_RETRIES" \
-baselineOnMigrate="$FLYWAY_BASELINE_ON_MIGRATE" \
-outOfOrder="$FLYWAY_OUT_OF_ORDER" \
-user="$POSTGRES_USER" \
-password="$POSTGRES_PASSWORD"
我的生成命令:
$ docker build -t reds-docker:latest -f "Dockerfile.reds" .
我的运行命令:
$ docker run --rm \
--env POSTGRES_USER="postgres" \
--env POSTGRES_PASSWORD="postgres" \
--env POSTGRES_DB="postgres" \
reds-docker:latest
当我运行container时,flyway尝试连接到数据库时,我得到了以下错误:
- 警告:连接错误:与172.17.0.2:5432的连接被拒绝。请检查主机名和端口是否正确以及邮局主管是否接受TCP/IP连接。(由连接被拒绝引起(连接被拒绝))*
启动后的完整日志:
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 dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Etc/UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Success. You can now start the database server using:
pg_ctl -D /var/lib/postgresql/data -l logfile start
initdb: 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.
waiting for server to start....2023-02-06 13:36:59.228 UTC [48] LOG: starting PostgreSQL 12.13 (Debian 12.13-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2023-02-06 13:36:59.229 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2023-02-06 13:36:59.237 UTC [49] LOG: database system was shut down at 2023-02-06 13:36:59 UTC
2023-02-06 13:36:59.239 UTC [48] LOG: database system is ready to accept connections
done
server started
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sh
WARNING: This version of Flyway is out of date. Upgrade to Flyway 9.14.1:https://flywaydb.org/documentation/learnmore/staying-up-to-date/?ref=v7.9.2_cmd-line
Flyway Community Edition 7.9.2 by Redgate
WARNING: Connection error: Connection to 172.17.0.2:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. (Caused by Connection refused (Connection refused)) Retrying in 1 sec...
WARNING: Connection error: Connection to 172.17.0.2:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. (Caused by Connection refused (Connection refused)) Retrying in 2 sec...
1条答案
按热度按时间s3fp2yjn1#
需要说明的是,
docker-entrypoint-initdb.d
中的脚本并不像您所说的那样在容器启动时运行,而是在数据库初始化时运行,因此它们只在初始化新数据库时运行,因此对于通常更改现有数据库的迁移来说并不适用。话虽如此,您的脚本不工作的原因是,当数据库正在初始化时,Postgres正在不接受TCP/IP连接的状态下运行。您只能使用Unix套接字与它对话。您可以在消息
listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
中的日志中看到这一点。我不知道Flyway是否支持通过Unix套接字连接,但是在数据库初始化脚本中不能通过TCP/IP连接。
启动数据库的代码是container startup script的以下部分:
正如你所看到的,它将
listen_addresses
设置为一个空字符串,这导致Postgres不监听任何TCP/IP端口。如果不使用修改后的启动脚本创建自己的映像,似乎没有办法修改这种行为。