连不上PostgreSQL主因是连接链路环节故障:Docker中host误填localhost(应为服务名如db)、PDO未启用异常模式(需设ATTR_ERRMODE=EXCEPTION)、pg_hba.conf未放行访问、pgsql扩展未安装或DATABASE_URL协议头错误(须为pgsql://)。

连不上不是 Symfony 本身不支持 PostgreSQL,而是连接链路上至少一个环节卡住了——常见是 host 填错、PDO::ATTR_ERRMODE 没开、或 pg_hba.conf 拦在了门口。
Doctrine 配置里 host 写 localhost 就错
Docker 环境下,PHP 容器里的 localhost 指的是它自己,不是 PostgreSQL 容器。必须用服务名(比如 db 或 postgres)作为 host 值。
- 检查
docker-compose.yml中 PostgreSQL 服务的container_name或hostname,例如hostname: db - 在 Symfony 的
.env或doctrine.yaml中,把DATABASE_URL的 host 部分改成那个名字:pgsql://user:pass@db:5432/dbname - 别写
@localhost:5432或@127.0.0.1:5432—— 这在容器内永远连不到对端
没开 PDO 异常模式,错误被静默吞掉
ThinkPHP6 和 Symfony 都一样:PostgreSQL 报错(比如用户不存在、库不存在、权限不足),如果没显式设置 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO 默认返回 false 或空结果,Symfony 日志里只记一条模糊的 QueryException,根本看不出哪错了。
- 确认
config/packages/doctrine.yaml中的options区域包含:options: { 'PDO::ATTR_ERRMODE': 'PDO::ERRMODE_EXCEPTION' } - 或者更稳妥:在
DATABASE_URL后追加&sslmode=disable(开发环境),避免 TLS 握手失败掩盖真实问题 - 运行
php bin/console doctrine:database:create测试;失败时看完整异常堆栈,而不是只盯浏览器 500
pg_hba.conf 没放行,连都连不进大门
Symfony 报 Connection refused 或 FATAL: no pg_hba.conf entry for host,基本就是 PostgreSQL 主动拒接。它不看应用配得对不对,先查访问白名单。
- 进入 PostgreSQL 容器:
docker exec -it <postgres-container-name> sh - 编辑
/var/lib/postgresql/data/pg_hba.conf,在 IPv4 local connections 下加一行:host all all 0.0.0.0/0 md5(仅开发) - 同时确认
postgresql.conf中listen_addresses = 'localhost,172.x.x.x'—— Docker 网络地址段要列进去,不能只留'localhost' - 改完重启 PostgreSQL 容器:
docker restart <postgres-container-name>
扩展没装或驱动名写错,PDO 根本不认识 pgsql
Driver not found: pgsql 或 Invalid driver specified 这类报错,说明 PHP 连 pgsql 这个驱动名都解析不了。
- 运行
php -r "print_r(PDO::getAvailableDrivers());",输出里必须有"pgsql"—— 不是pg,也不是postgres - Docker 镜像里要装
php-pgsql包(Alpine 用apk add php82-pgsql,Debian 用apt-get install php-pgsql) - Symfony 的
DATABASE_URL必须以pgsql://开头,写成postgres://或postgresql://会 fallback 到 MySQL 驱动
最容易被忽略的是:Docker Compose 里两个同名服务定义导致环境变量被覆盖,你以为的密码其实是另一个配置块里的值。用 docker-compose config 看最终生效的配置,比猜强十倍。


















