k3n*_*jiy 1 postgresql docker docker-compose
我曾经使用脚本 ( /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?
Run Code Online (Sandbox Code Playgroud)
该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."
Run Code Online (Sandbox Code Playgroud)
我正在使用 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
Run Code Online (Sandbox Code Playgroud)
现在我不明白的是为什么似乎通常与尝试从不同的机器或容器连接到 postgres 数据库相关的连接错误。但是脚本本身在 postgres 容器中运行,并且一个卷将包含转储的目录连接到容器中。psql使用在容器内运行命令docker exec -it container_name bash工作正常并且转储在那里。为什么psql从容器内手动执行命令时命令有效,但通过 执行时无效/docker-entrypoint-initdb.d/db_init.sh?
看起来这个提交破坏了你的脚本。
解释:
PostgreSQL 不仅可以通过 TCP/IP 接受连接,还可以通过 UNIX 套接字接受连接。该-h localhost参数告诉psql使用 TCP 连接而不是 UNIX 套接字。
如果您查看当前的docker-entrypoint.sh版本,您会看到,在/docker-entrypoint-initdb.dPostgreSQL 中执行脚本的过程中仅侦听 UNIX 套接字,并且启动日志显示:
LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
Run Code Online (Sandbox Code Playgroud)
这意味着psql -h localhost不会连接到数据库,因为 PostgreSQL 不侦听 IP 套接字。您必须使用psql without -h localhost option 才能使其使用 UNIX 套接字而不是 TCP 连接。
但是为什么psql -h localhost手动运行有效呢?
如果你docker-entrypoint.sh再看一遍,你会看到当所有的 init 脚本被执行时,PostgreSQL 被停止,然后在正常(操作)模式下再次启动,在这种模式下它在 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"
Run Code Online (Sandbox Code Playgroud)
因此,当启动过程完成后,您可以使用TCP连接连接到PostgreSQL,从而进入容器并运行psql -h localhost成功。
| 归档时间: |
|
| 查看次数: |
924 次 |
| 最近记录: |