无法通过本地端口转发连接Docker Compose部署的PostgreSQL
问题背景
在Windows 11系统中,通过Docker Compose部署PostgreSQL 12.1-alpine镜像后,本地使用psql命令或Node.js程序通过端口转发连接数据库时,持续出现密码认证失败错误,但通过docker exec进入容器内部可以正常访问数据库。
Docker Compose配置
services: postgres: container_name: cnc-matches image: postgres:12.1-alpine ports: - '5432:5432' environment: POSTGRES_USER: dbuser POSTGRES_PASSWORD: pass POSTGRES_DB: cnc-matches
本地连接错误示例
执行本地psql连接命令:
C:\Users\danie\Desktop\dev\cnc-db\db-setup>psql -h "localhost" -p "5432" -U dbuser Password for user dbuser: pass psql: error: connection to server at "localhost" (::1), port 5432 failed: FATAL: password authentication failed for user "dbuser"
创建新用户tester后尝试连接,同样报错:
C:\Users\danie\Desktop\dev\cnc-db\db-setup>psql -h "localhost" -p "5432" -U tester Password for user tester: tester psql: error: connection to server at "localhost" (::1), port 5432 failed: FATAL: password authentication failed for user "tester"
容器内正常访问情况
通过docker exec进入容器可以正常连接并操作数据库:
C:\Users\danie\Desktop\dev\cnc-db\db-setup>docker exec -it cnc-matches psql -U dbuser cnc-matches psql (12.1) Type "help" for help. cnc-matches=# \du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- dbuser | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
尝试创建新用户并修改密码后,容器内可以正常识别,但本地仍无法连接:
cnc-matches=# CREATE USER tester WITH PASSWORD 'tester'; CREATE ROLE cnc-matches=# \du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- dbuser | Superuser, Create role, Create DB, Replication, Bypass RLS | {} tester | | {}
解决建议
检查端口占用情况:
Windows下执行netstat -ano | findstr :5432,确认本地5432端口是否被其他PostgreSQL服务或进程占用。如果有,停止占用进程,或者修改Docker Compose的端口映射为5433:5432,之后用psql -h localhost -p 5433 -U dbuser尝试连接。修改PostgreSQL认证配置:
进入容器内部:docker exec -it cnc-matches bash,找到/var/lib/postgresql/data/pg_hba.conf文件,添加或修改以下两行配置,确保允许外部连接使用md5认证:host all all 0.0.0.0/0 md5 host all all ::/0 md5修改后重启容器:
docker-compose restart postgres,再尝试本地连接。验证密码输入正确性:
避免在命令提示符输入密码时误加空格或不可见字符,可尝试直接在命令行传递密码(仅用于测试):psql -h localhost -p 5432 -U dbuser -d cnc-matches --password=pass尝试使用容器IP连接:
先获取容器IP:docker inspect cnc-matches | findstr IPAddress,然后用容器IP代替localhost连接:psql -h [容器IP] -p 5432 -U dbuser
内容的提问来源于stack exchange,提问作者Daniel40392

