gpt4 book ai didi

postgresql - 在/docker-entrypoint-initdb.d/db_init.sh 中运行 psql 命令时出错(psql : could not connect to server: Connection refused)

转载 作者:行者123 更新时间:2023-11-29 12:40:44 25 4
gpt4 key购买 nike

我曾经使用脚本 (/docker-entrypoint-initdb.d/db_init.sh) 循环遍历复制到 postgres 容器中的文件夹中的数据库转储并恢复它们。它曾经工作得很好,但最近停止工作了。

我收到以下错误:

postgres_server_1  | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/db_init.sh
postgres_server_1 | --> db_init.sh: Found /dumps/dataset_1.dump as dataset_1
postgres_server_1 | psql: could not connect to server: Connection refused
postgres_server_1 | Is the server running on host "localhost" (127.0.0.1) and accepting
postgres_server_1 | TCP/IP connections on port 5432?

db_init.sh 脚本循环遍历包含数据库转储的文件夹并检查数据库是否已经存在。如果不是,它会恢复转储。

/docker-entrypoint-initdb.d/db_init.sh 内容:

shopt -s nullglob
for i in /dumps/*.dump;
do
db_name=${i##*/}
db_name=${db_name%.dump}
echo "--> db_init.sh: Found $i as $db_name"

if psql -U postgres -h localhost -lqt | cut -d \| -f 1 | grep -qw ${db_name}; then
echo "--> db_init.sh: Database ${db_name} already exists."
else
echo "--> db_init.sh: Setting up database: ${db_name}"
createdb -U postgres -h localhost-T template0 ${db_name}
psql -U postgres -h localhost ${db_name} < ${i}
fi
done
echo "--> db_init.sh: Setup complete."

我正在使用 docker-compose 来启动 postgres 容器(和其他一些容器)。

docker-compose.yml内容:

version: '3'

services:
postgres_server:
image: postgres
volumes:
- /etc/localtime:/etc/localtime:ro
- ./data/dumps:/dumps:ro
- ./scripts/db_init.sh:/docker-entrypoint-initdb.d/db_init.sh
environment:
- TZ=Europe/Berlin
restart: always

volumes:
postgres_data:
driver: local

现在我不明白的是,为什么似乎有一个连接错误通常与尝试从不同的机器或容器连接到 postgres 数据库有关。但是脚本本身在 postgres 容器中运行,并且卷将包含转储的目录连接到容器中。使用 docker exec -it container_name bash 从容器内运行 psql 命令效果很好,转储就在那里。为什么 psql 命令在从容器内手动执行时有效,但在通过 /docker-entrypoint-initdb.d/db_init.sh 执行时却无效?

最佳答案

看起来像this commit破坏了你的脚本。

解释:

PostgreSQL 不仅可以通过 TCP/IP 接受连接,还可以通过 UNIX 套接字接受连接。 -h localhost 参数告诉 psql 使用 TCP 连接而不是 UNIX 套接字。

如果您查看当前的 docker-entrypoint.sh版本,您会看到,在 /docker-entrypoint-initdb.d 中的脚本执行期间,PostgreSQL 仅监听 UNIX 套接字,启动日志显示:

LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"

这意味着 psql -h localhost 将不会连接到数据库,因为 PostgreSQL 不会监听 IP 套接字。您必须使用 psql 不带 -h localhost 选项以使其使用 UNIX 套接字而不是 TCP 连接。

但为什么手动运行 psql -h localhost 可以工作?

如果您再次查看 docker-entrypoint.sh,您会看到当所有初始化脚本执行时,PostgreSQL 正在 stopped然后 started再次处于正常(操作)模式,在该模式下它在 UNIX 和 IP 套接字上监听:

LOG:  listening on IPv4 address "0.0.0.0", port 5432
LOG: listening on IPv6 address "::", port 5432
LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"

因此,当启动过程完成后,您可以使用TCP连接连接到PostgreSQL,从而进入容器并运行psql -h localhost成功。

关于postgresql - 在/docker-entrypoint-initdb.d/db_init.sh 中运行 psql 命令时出错(psql : could not connect to server: Connection refused),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51659972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com