PostgreSQL 连接中禁用 SSL 的完整配置指南

20次阅读

PostgreSQL 连接中禁用 SSL 的完整配置指南

当使用 sequelize 连接 docker 中的 postgresql 容器时,若未显式禁用 ssl,sequelize 会默认尝试启用 ssl,而官方 postgres:latest 镜像默认不支持 ssl,从而报错 “the server does not support ssl connections”。解决方法是在连接 url 或 sequelize 配置中明确关闭 ssl。

docker Compose 环境中,PostgreSQL 容器(如 postgres:latest)默认以非 SSL 模式运行,不生成或加载 SSL 证书。而 Sequelize(尤其是较新版本)在使用 dialect: ‘postgres’ 时,会依据环境或底层 pg 驱动策略,自动尝试启用 SSL 连接(例如当检测到 DATABASE_URL 存在、或系统环境含 PGSSLMODE 但未被正确透传时),导致连接失败。

关键点在于:.env.development 中的 DATABASE_URL(如有)或 Sequelize 初始化参数,必须显式声明 SSL 禁用策略——仅在 docker-compose.yml 中设置 PGSSLMODE=disable 对 node.js 应用完全无效,因为该变量仅作用于 PostgreSQL 容器自身,不会传递给你的 express 应用。

✅ 推荐解决方案(二选一,推荐方案一):

方案一:通过连接 URL 显式禁用 SSL(最清晰、最可靠)
确保 .env.development 中的 DATABASE_URL 包含 ?sslmode=disable 参数:

# .env.development DATABASE_URL=postgres://postgres:admin123@database:5432/ticketsellermadrid_dev?sslmode=disable

然后在代码中直接使用该 URL 初始化 Sequelize:

import { Sequelize } from 'sequelize';  const sequelize = new Sequelize(process.env.DATABASE_URL!, {   dialect: 'postgres',   dialectOptions: {     ssl: false, // 双重保险:显式关闭   },   logging: console.log, });

⚠️ 注意:sslmode=disable 是 PostgreSQL 协议标准参数;ssl: false 是 pg 驱动层选项,二者配合使用可彻底规避 SSL 尝试。

方案二:纯对象配置 + 显式 ssl: false
若坚持使用独立参数(如 username/host 等),必须在 dialectOptions 中强制关闭 SSL:

const sequelize = new Sequelize({   username: process.env.DB_OWNER,   password: process.env.DB_PASSWORD,   host: process.env.DB_HOST, // e.g., 'database'   port: parseInt(process.env.DB_PORT || '5432'),   database: process.env.DB_NAME,   dialect: 'postgres',   dialectOptions: {     ssl: false, // ✅ 必须设置!否则仍可能触发 SSL handshake   }, });

❌ 常见误区排除:

  • PGSSLMODE=disable 和 PGREQUIRESSL=0 仅影响 PostgreSQL 服务端行为,不影响客户端连接逻辑
  • ssl: false 必须置于 dialectOptions 内,而非顶层配置;
  • 若使用连接池(如自定义 Pool),需确保 ssl: false 传入 new Pool({ ssl: false }),但 Sequelize 已封装该逻辑,无需手动创建 Pool。

✅ 最终验证方式:启动容器后,在 app 容器内执行测试连接:

docker exec -it  node -e " const { Client } = require('pg'); new Client({   connectionString: 'postgres://postgres:admin123@database:5432/ticketsellermadrid_dev?sslmode=disable' }).connect().then(() => console.log('✅ SSL-free connection OK')).catch(e => console.error('❌', e.message)); "

总结:PostgreSQL 容器本身无需 SSL 配置,但客户端(Sequelize)必须主动声明不使用 SSL。优先采用带 ?sslmode=disable 的 DATABASE_URL 初始化方式,结构清晰、兼容性强,是 Docker 开发环境的标准实践。

text=ZqhQzanResources