如何配置PostgreSQL允许Docker容器连接(非全开放模式)
我完全懂你的处境——想让本地跑的Docker容器连上主机的PostgreSQL,但又不想把数据库完全开放给所有地址,还担心Docker自动分配的子网哪天变了,之前的配置就白费了。咱们一步步来解决这个问题:
1. 先搞清楚Docker容器所在的子网(可选固定子网)
首先得确定你的容器到底在哪个子网里,避免瞎猜。你可以用这两个命令查:
- 先看容器关联的网络:
docker inspect <你的容器名称> | grep -A 10 "Networks" - 再查这个网络的子网段:
docker network inspect <上面查到的网络名称> | grep -A 5 "Subnet"
从你的tshark输出看,容器IP是192.168.32.2,对应的子网大概率是192.168.32.0/24,但建议你自己确认下更稳妥。
如果担心Docker下次重建容器时子网变化,可以在docker-compose.yaml里固定子网,这样不管怎么重启、重建,子网都不会变:
networks: default: ipam: config: - subnet: 192.168.32.0/24 # 换成你查到的子网,或者自己指定一个合适的
2. 修改PostgreSQL的监听地址
找到你的PostgreSQL配置文件postgresql.conf(通常在/var/lib/postgresql/<版本>/main/或者/etc/postgresql/<版本>/main/目录下),修改listen_addresses参数:
原来的可能是:
listen_addresses = '127.0.0.1'
改成同时监听主机的Docker网关地址(从你的tshark看是172.17.0.1)和本地回环:
listen_addresses = '127.0.0.1,172.17.0.1'
这样PostgreSQL就会在主机的Docker网关上监听5432端口,容器就能访问到了。
3. 配置PostgreSQL的访问控制规则(pg_hba.conf)
接下来要限制只有Docker子网的容器能连接,避免开放给无关地址。找到pg_hba.conf(和postgresql.conf同目录),在文件末尾添加一行规则:
host all all 192.168.32.0/24 scram-sha-256
- 把
192.168.32.0/24换成你查到的(或固定的)Docker子网 scram-sha-256是PostgreSQL 10+推荐的认证方式,如果你的版本比较旧,换成md5就行
4. 重启PostgreSQL服务,测试连接
修改完配置后,重启PostgreSQL生效:
sudo systemctl restart postgresql
然后到你的Docker容器里测试连接:
psql -h host.docker.internal -U <你的PostgreSQL用户名> -d <要连接的数据库名>
为啥之前连接被拒绝?
从你的tshark日志能看出来:容器(192.168.32.2)向主机的172.17.0.1:5432发了连接请求,但PostgreSQL之前只监听127.0.0.1:5432,主机的172.17.0.1这个IP上根本没开5432端口,所以直接返回了RST包拒绝连接。现在咱们改了监听地址和访问规则,这个问题就解决了。
备注:内容来源于stack exchange,提问作者Chris Stryczynski




