Strapi连接DigitalOcean PostgreSQL数据库时出现SSL证书错误
问题描述
我正在运行一个连接DigitalOcean PostgreSQL数据库的Strapi应用,遇到了「self-signed certificate(自签名证书)」错误。已经正确设置DATABASE_SSL环境变量,且在config/database.js中配置了DigitalOcean提供的CA证书,但连接时仍存在SSL验证问题,求解决Strapi-PostgreSQL架构下的SSL证书信任问题。
错误信息
│ Error: self-signed certificate │ │ at TLSSocket.onConnectSecure (node:_tls_wrap:1545:34) │ │ at TLSSocket.emit (node:events:513:28) │ │ at TLSSocket.emit (node:domain:489:12) │ │ at TLSSocket._finishInit (node:_tls_wrap:959:8) │ │ at ssl.onhandshakedone (node:_tls_wrap:743:12)
当前数据库配置代码
var fs = require('fs'); module.exports = ({ env }) => ({ connection: { client: 'postgres', connection: { host: env('DATABASE_HOST'), port: env.int('DATABASE_PORT'), database: env('DATABASE_NAME', 'strapi'), user: env('DATABASE_USERNAME','strapi'), password: env('DATABASE_PASSWORD','strapi'), ssl: env.bool('DATABASE_SSL', false) ? { rejectUnauthorized: env.bool('DATABASE_SSL_REJECT_UNAUTHORIZED', false), ca: fs.readFileSync(env('PATH_TO_CA_CERT')).toString(), } : undefined, }, acquireConnectionTimeout: 1000000, pool: { min: 0, max: 4, acquireTimeoutMillis: 300000, createTimeoutMillis: 300000, destroyTimeoutMillis: 300000, idleTimeoutMillis: 30000, reapIntervalMillis:1000, createRetryIntervalMillis: 2000 }, }, });
解决方案
检查CA证书的有效性
确认PATH_TO_CA_CERT环境变量指向的是DigitalOcean提供的CA证书绝对路径,证书内容完整且为PEM格式(以-----BEGIN CERTIFICATE-----开头,-----END CERTIFICATE-----结尾)。可通过终端命令cat ${PATH_TO_CA_CERT}验证内容是否未被修改或截断。修正SSL验证逻辑
DigitalOcean PostgreSQL强制要求SSL连接,确保DATABASE_SSL设为true。将rejectUnauthorized临时设为true,如果此时连接失败,说明CA证书配置有误,需重新从DigitalOcean控制台获取正确的证书;若设为false能连接,证明当前CA证书不被信任,必须替换为正确的证书后再开启rejectUnauthorized。直接嵌入CA证书内容测试
若读取文件方式存在问题,可临时将CA证书的完整字符串直接写入配置(生产环境建议仍用文件或环境变量),示例:ssl: { rejectUnauthorized: true, ca: `-----BEGIN CERTIFICATE----- [DigitalOcean提供的完整CA证书内容] -----END CERTIFICATE-----` }核对数据库连接参数
确认DATABASE_HOST是DigitalOcean PostgreSQL实例的正确域名(格式通常为xxx.db.ondigitalocean.com),端口为默认的25060,用户名包含集群标识(如doadmin),避免因参数错误导致SSL握手失败。升级依赖版本
旧版本的Strapi或其依赖的pg驱动可能存在SSL兼容问题,执行npm update strapi或npm update pg升级到最新稳定版,再尝试连接。
内容的提问来源于stack exchange,提问作者Ouen A

