Docker测试容器无法连接PostgreSQL容器的原因排查
我通过以下命令运行PostgreSQL Docker容器:
docker run -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust -v /var/lib/postgresql/data:/var/lib/postgresql/data postgis/postgis
pg_hba.conf文件内容如下:
# warning trust is enabled for all connections host all all all trust
从宿主机发起连接请求:
psql -h localhost -U fake
数据库日志返回:
FATAL: role "fake" does not exist
测试Dockerfile内容如下:
FROM postgres:latest RUN apt-get update && apt-get install -y postgresql-client CMD ["psql", "-U", "fake", "-h", "localhost", "-p", "5432"]
运行测试Docker容器时出现如下错误:
psql: error: connection to server at "localhost" (::1), port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
且数据库日志无任何记录。请问为何无法从测试容器发起请求?
核心问题:容器的localhost不是宿主机
Docker容器默认有独立的网络空间,每个容器的localhost指向自己的回环接口,和宿主机的localhost完全是两回事。测试容器里用localhost连接,其实是在找容器内部的PostgreSQL服务,但这个测试容器只装了客户端,根本没启动数据库,自然会被拒绝,而且请求根本没发到主数据库容器,所以主容器日志毫无记录。
解决方式
有两种常用方案:
直接用宿主机IP或共享宿主机网络
- 如果你想保留容器默认网络,把测试容器连接命令里的
localhost换成宿主机的实际IP(比如192.168.3.10),修改Dockerfile的CMD:CMD ["psql", "-U", "fake", "-h", "你的宿主机IP", "-p", "5432"] - 或者启动测试容器时用
--net=host模式,让容器共享宿主机网络栈,此时localhost就指向宿主机:docker run --net=host 你的测试镜像名称
- 如果你想保留容器默认网络,把测试容器连接命令里的
创建自定义Docker网络,让两个容器互通
- 先创建自定义网络:
docker network create pg-net - 用这个网络启动PostGIS容器,并指定容器名:
docker run -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust -v /var/lib/postgresql/data:/var/lib/postgresql/data --network pg-net --name postgis-server postgis/postgis - 修改测试Dockerfile的CMD,用容器名
postgis-server作为主机名:CMD ["psql", "-U", "fake", "-h", "postgis-server", "-p", "5432"] - 启动测试容器时加入同一网络:
docker run --network pg-net 你的测试镜像名称
- 先创建自定义网络:
额外提醒:fake角色的问题
就算解决了网络问题,你还是会遇到FATAL: role "fake" does not exist的错误。PostgreSQL默认只创建postgres超级用户,需要手动创建fake角色:
# 从宿主机用postgres用户连接数据库 psql -h localhost -U postgres # 在数据库内创建角色 CREATE ROLE fake WITH LOGIN;
内容的提问来源于stack exchange,提问作者dos4dev

