我正在尝试将我的Node.js/Sequelizer应用程序中的sequilizer模型迁移到托管在Google Cloud上的PostgreSQL数据库。GCP要求我使用SSL(或一些复杂的代理)进行连接。
当我运行以下命令时:NODE_ENV=production npx sequelize db:migrate
我得到错误:
Sequelize CLI [Node: 19.0.0, CLI: 6.6.0, ORM: 6.29.3]
** config.js **
Loaded configuration file "config/config.js".
Using environment "production".
**ERROR: The server does not support SSL connections**
这是我第一次使用Sequelizer和Google Cloud SQL。我感谢任何帮助。
我可以使用Postico 2上的SSL证书进行连接(连接时确认是TLS 1.3连接),也可以使用BeeKeeper Studio进行连接。在GCP控制台中,我将其设置为仅需要SSL连接(我的项目需要此连接)。
我还使用.sequelizerc设置来覆盖config以调用我的config.js(解决加载证书的其他挑战的唯一方法):
const fs = require('fs');
const path = require('path');
console.log("** config.js **");
module.exports = {
development: {
dialect: "sqlite",
storage: "./database_dev.sqlite3"
},
test: {
username: process.env.CI_DB_USERNAME,
password: process.env.CI_DB_PASSWORD,
database: process.env.CI_DB_NAME,
host: '127.0.0.1',
port: 5432,
dialect: 'postgres'
},
production: {
username: process.env.PROD_DB_USERNAME,
password: process.env.PROD_DB_PASSWORD,
database: process.env.PROD_DB_NAME,
host: process.env.PROD_DB_HOSTNAME,
port: process.env.PROD_DB_PORT,
dialect: 'postgres',
ssl: true,
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false,
ca: fs.readFileSync(path.join(__dirname,'..','ssl','server-ca.pem')),
cert: fs.readFileSync(path.join(__dirname,'..','ssl','client-cert.pem')),
key: fs.readFileSync(path.join(__dirname,'..','ssl','client-key.pem'))
}
},
debug: true
}
};
Dev和Test均已成功迁移。
更新3/21/2023
如下所示,我尝试使用以下连接:
const fs = require('fs');
const { Client, Pool } = require("pg");
const config = {
user: process.env.PROD_DB_USERNAME,
password: process.env.PROD_DB_PASSWORD,
database: process.env.PROD_DB_NAME,
host: process.env.PROD_DB_HOSTNAME,
port: process.env.PROD_DB_PORT,
application_name: "sequelizer-practice",
// this object will be passed to the TLSSocket constructor
ssl: {
rejectUnauthorized: false,
ca: fs.readFileSync(__dirname + "/ssl/server-ca.pem").toString(),
key: fs.readFileSync(__dirname + "/ssl/client-key.pem").toString(),
cert: fs.readFileSync(__dirname + "/ssl/client-cert.pem").toString(),
},
};
const client = new Client(config);
client.connect((err) => {
if (err) {
console.error("error connecting", err.stack);
} else {
// console.log("connected");
client.query("SELECT NOW()", (err, res) => {
if (err) throw err;
console.log(res);
client.end();
});
}
});
const pool = new Pool(config);
pool.connect()
.then((client) => {
console.log("connected");
client.release();
})
.catch((err) => console.error("error connecting", err.stack))
.then(() => pool.end());
这连接并从数据库返回了请求的时间戳。但我仍然不知道我在尝试做同样的事情时做错了什么。
1条答案
按热度按时间fhg3lkii1#
我想我发现了这个问题(虽然不是那么简单)。在阅读了Github上Sequelizer Discussion的这篇文章中的评论后,我了解到选项应该直接传递给pg。因为我使用pg,所以我能够缩小差异。
Connect to postgres with ssl mode #15636
结果是Sequelizer为生产配置选择变量的方式在使用.env中的值时出现了问题
当我将用户名、数据库、主机和密码的字符串直接硬编码到config.js中时,它解决了这个问题。
给我的一个教训是,IP地址不会作为环境变量的字符串出现。但请注意,这本身并没有解决这个问题。我必须硬编码用户名和数据库,否则它会试图与我的操作系统用户名连接。