Postgres 重启后不会侦听 Docker 主机 IP 地址,直到 Postgres 重新启动

Vir*_*olf 2 postgresql docker

我有一个全新的 Debian 9,带有 Docker 18.09(从官方 Docker 存储库安装)和 Postgres 9.6。我已编辑/etc/postgresql/9.6/main/postgresql.conf设置listen_addresses参数:

listen_addresses = '127.0.0.1,172.17.0.1'
Run Code Online (Sandbox Code Playgroud)

进行更改并重新启动 Postgres 后,我的 Docker 容器可以毫无问题地连接到 172.17.0.1 的 Postgres。当我重新启动整个操作系统时,问题就出现了,Postgres 将不会侦听 172.17.0.1,直到我重新启动 Postgres 本身。我已经交换了地址的顺序postgresql.conf,但没有效果,running show listen_addresses;inpsql 表示它正在侦听我指定的两个端口,但sudo netstat -na显示它仅侦听 127.0.0.1:

$ sudo netstat -na
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
Run Code Online (Sandbox Code Playgroud)

重新启动 Postgres ( systemctl restart postgres),现在它也在侦听 172.17.0.1:

$ sudo netstat -na
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN
tcp        0      0 172.17.0.1:5432         0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
Run Code Online (Sandbox Code Playgroud)

这意味着在启动时启动并连接到 Postgres 的 Docker 容器无法自动启动,因为它们收到“连接被拒绝”错误。

Vir*_*olf 6

在做了更多测试之后,我意识到这似乎是 Docker 和 Postgres 启动的时间问题,我猜像 Docker 接口之类的东西直到 Docker 本身启动或其他东西才会出现,因此 Postgres 不能听听它,因为它还不存在。

2023年更新

事实证明,有一种更好的方法可以通过 systemd“插入单元”来完成此操作,如此处所述

创建目录/lib/systemd/system/postgresql@.service.d并在其中创建一个docker.conf包含以下内容的文件:

[Unit]
Wants=docker.service
After=docker.service
Run Code Online (Sandbox Code Playgroud)

这在原始答案中完成了相同的事情,只是它保留了系统安装的单元文件。

原答案

我将其复制/lib/systemd/system/postgresql@.service(是的,其中@包含)/etc/systemd/system/并在该[Unit]部分中将其设置为仅在Docker 启动后启动:

[Unit]
...
After=docker.service
Run Code Online (Sandbox Code Playgroud)

然后配置我的自定义单元,启动 Docker 容器仅在 Postgres 之后启动(而不是 Docker,因为 Postgres 无论如何都不会在 Docker 之后启动):

[Unit]
...
Wants=postgresql.service
Run Code Online (Sandbox Code Playgroud)

现在一切都按预期进行!