
当使用 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 -itnode -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 开发环境的标准实践。










