如何让heroku为数据库使用环境配置
How to get heroku to use environmental config for DB
Heroku 在日志中识别出它正在尝试连接到我未使用(但使用过一次)的 MongoDB 分片。错误消息说:
"failed to connect to server
[swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017]"
但我不知道它为什么要尝试连接到该服务器。
我正在将 node.js
应用程序部署到 heroku
。 Heroku 链接到我的 MLAB
数据库。
我可以通过 mongo shell 与数据库进行交互。当我在本地服务器上 运行 时,postman 可以对 MLAB 数据库进行所有 CRUD 操作。但是,当我在邮递员中使用 heroku 网址时,出现 503 错误。日志显示“MongoNetworkError
”和“TransientTransactionError
”。但我认为,主要问题是它试图接触到我不再 运行 的 Cloud Atlas 分片。我的代码中没有连接字符串;它们都是由环境变量设置的。我已经更新并仔细检查我的本地系统是否设置为新的连接字符串,并且 heroku
是否配置为新的连接字符串。我不知道 heroku
(或 mlab?或 mongodb?)从哪里获取旧的连接碎片。
我已尝试取消设置 heroku
和本地服务器的配置。我试图在 cluster atlas
上找到碎片的旧实例,但找不到。一切正常,直到我尝试使用邮递员联系 heroku 地址。
我在 heroku 文档中找不到任何内容,或者 mongo 除了单击连接字符串并将它们放入代码之外,我还没有说什么。我还尝试将正确的连接字符串直接放入代码中——没有变化。
我认为我需要更改某处的默认设置,但我不知道在哪里。
我认为代码不会有帮助,但为了显示代码(全部在 Github 上)
生产配置:
{
"name": "SwarmAge - Production",
"mail": {
"host": "prod-mail-server"
},
"title": "Welcome to the Swarm Age"
}
自定义环境变量
{
"mail": {
"password": "SwarmAge_password"
},
"jwtPrivateKey": "SwarmAge_jwtPrivateKey",
"connectionString": "SwarmAge_db"
}
index.js
const express = require("express");
const app = express();
const winston = require("winston");
require("./startup/logging")();
require("./startup/routes")(app);
require("./startup/db")();
require("./startup/config")();
require("./startup/validation")();
require("./startup/prod")(app);
require("./startup/status")(app);
app.set("view engine", "pug");
app.set("views", "./views");
const port = process.env.PORT || 3000;
const server = app.listen(port, () =>
winston.info(`Listening on port ${port}`)
);
module.exports = server;
启动配置
const config = require("config");
module.exports = function() {
if (!config.get("jwtPrivateKey")) {
throw new Error("FATAL ERROR: jwtPrivateKey is not defined.");
}
};
启动数据库
module.exports = function() {
const db = config.get("connectionString");
mongoose
.connect(db, {
useNewUrlParser: true,
useFindAndModify: false
})
.then(() => winston.info(`Connected to ${db} . . .`));
};
从终端,
heroku 配置(转到 Heroku,它从哪里获取碎片?):--------
C:\Users\tedgo\voter>heroku config
swarmage-backend-190625 配置变量
NODE_ENV: production
SwarmAge_db: mongodb://AdminGLOC:fakopassword@ds155461.mlab.com:55461/heroku_6qxb8b19
SwarmAge_jwtPrivateKey: hidden
SwarmAge_password: not-important
jwtPrivateKey: took-this-out-as-well
我的设置(转到 Cluster Atlas——这有效)
SwarmAge_db=mongodb+srv://AdminGLOC:not-my-real-password@swarmage-0idyv.gcp.mongodb.net/development?retryWrites=true
这是日志中的错误消息:
cat uncaughtExceptions.log
{"error":{"name":"MongoNetworkError","errorLabels":["TransientTransactionError"]},"level":"error","message":"uncaughtException:
failed to connect to server
[swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect
[MongoError: bad auth Authentication failed.]\nMongoNetworkError:
failed to connect to server
[swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect
[MongoError: bad auth Authentication failed.]\n at Pool.
(C:\Users\tedgo\node_modules\mongodb-core\lib\topologies\server.js:431:11)\n
at Pool.emit (events.js:189:13)\n at connect
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\pool.js:557:14)\n
at callback
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:109:5)\n
at provider.auth.err
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:352:21)\n
at _authenticateSingleConnection
(C:\Users\tedgo\node_modules\mongodb-core\lib\auth\auth_provider.js:66:11)\n
at sendAuthCommand
(C:\Users\tedgo\node_modules\mongodb-core\lib\auth\scram.js:215:18)\n
at Connection.messageHandler
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:334:5)\n
at Connection.emit (events.js:189:13)\n at processMessage
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connection.js:364:10)\n
at TLSSocket.
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connection.js:533:15)\n
at TLSSocket.emit (events.js:189:13)\n at addChunk
(_stream_readable.js:284:12)\n at readableAddChunk
(_stream_readable.js:265:11)\n at TLSSocket.Readable.push
(_stream_readable.js:220:10)\n at TLSWrap.onStreamRead [as onread]
(internal/stream_base_commons.js:94:17)","stack":"MongoNetworkError:
failed to connect to server
[swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect
[MongoError: bad auth Authentication failed.]\n at Pool.
(C:\Users\tedgo\node_modules\mongodb-core\lib\topologies\server.js:431:11)\n
at Pool.emit (events.js:189:13)\n at connect
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\pool.js:557:14)\n
at callback
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:109:5)\n
at provider.auth.err
(C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:352:21)\n
at _authenticateSingleConnection
(C:\Users\tedgo\node_modules\mongodb-core\lib\auth\auth_provider.js:66:11)\n
at sendAuthCommand
(C:\Users\tedgo\node_modules\mongodb-core\lib\auth\sc
这个答案来自编码器 Santiago Beltram。
-几个问题。
--首先,default.config 文件需要保存在 custom-environmental-variable 中找到的所有变量。它没有。
--其次,在models.supporters.js中有一个错误,其中"require('jsonwebtoken')"被写成驼峰式"require('jasonWebToken')"。这不需要适当的程序。
--第三,并非所有依赖项都出现在 package.json 文件中。因此 heroku 不知道要包含它们。
在使用 --save 标志修复代码并在 package.json 中包含缺少的依赖项后,程序已成功部署到 heroku。
Heroku 在日志中识别出它正在尝试连接到我未使用(但使用过一次)的 MongoDB 分片。错误消息说:
"failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017]"
但我不知道它为什么要尝试连接到该服务器。
我正在将 node.js
应用程序部署到 heroku
。 Heroku 链接到我的 MLAB
数据库。
我可以通过 mongo shell 与数据库进行交互。当我在本地服务器上 运行 时,postman 可以对 MLAB 数据库进行所有 CRUD 操作。但是,当我在邮递员中使用 heroku 网址时,出现 503 错误。日志显示“MongoNetworkError
”和“TransientTransactionError
”。但我认为,主要问题是它试图接触到我不再 运行 的 Cloud Atlas 分片。我的代码中没有连接字符串;它们都是由环境变量设置的。我已经更新并仔细检查我的本地系统是否设置为新的连接字符串,并且 heroku
是否配置为新的连接字符串。我不知道 heroku
(或 mlab?或 mongodb?)从哪里获取旧的连接碎片。
我已尝试取消设置 heroku
和本地服务器的配置。我试图在 cluster atlas
上找到碎片的旧实例,但找不到。一切正常,直到我尝试使用邮递员联系 heroku 地址。
我在 heroku 文档中找不到任何内容,或者 mongo 除了单击连接字符串并将它们放入代码之外,我还没有说什么。我还尝试将正确的连接字符串直接放入代码中——没有变化。
我认为我需要更改某处的默认设置,但我不知道在哪里。
我认为代码不会有帮助,但为了显示代码(全部在 Github 上)
生产配置:
{
"name": "SwarmAge - Production",
"mail": {
"host": "prod-mail-server"
},
"title": "Welcome to the Swarm Age"
}
自定义环境变量
{
"mail": {
"password": "SwarmAge_password"
},
"jwtPrivateKey": "SwarmAge_jwtPrivateKey",
"connectionString": "SwarmAge_db"
}
index.js
const express = require("express");
const app = express();
const winston = require("winston");
require("./startup/logging")();
require("./startup/routes")(app);
require("./startup/db")();
require("./startup/config")();
require("./startup/validation")();
require("./startup/prod")(app);
require("./startup/status")(app);
app.set("view engine", "pug");
app.set("views", "./views");
const port = process.env.PORT || 3000;
const server = app.listen(port, () =>
winston.info(`Listening on port ${port}`)
);
module.exports = server;
启动配置
const config = require("config");
module.exports = function() {
if (!config.get("jwtPrivateKey")) {
throw new Error("FATAL ERROR: jwtPrivateKey is not defined.");
}
};
启动数据库
module.exports = function() {
const db = config.get("connectionString");
mongoose
.connect(db, {
useNewUrlParser: true,
useFindAndModify: false
})
.then(() => winston.info(`Connected to ${db} . . .`));
};
从终端, heroku 配置(转到 Heroku,它从哪里获取碎片?):--------
C:\Users\tedgo\voter>heroku config
swarmage-backend-190625 配置变量
NODE_ENV: production
SwarmAge_db: mongodb://AdminGLOC:fakopassword@ds155461.mlab.com:55461/heroku_6qxb8b19
SwarmAge_jwtPrivateKey: hidden
SwarmAge_password: not-important
jwtPrivateKey: took-this-out-as-well
我的设置(转到 Cluster Atlas——这有效)
SwarmAge_db=mongodb+srv://AdminGLOC:not-my-real-password@swarmage-0idyv.gcp.mongodb.net/development?retryWrites=true
这是日志中的错误消息:
cat uncaughtExceptions.log {"error":{"name":"MongoNetworkError","errorLabels":["TransientTransactionError"]},"level":"error","message":"uncaughtException: failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect [MongoError: bad auth Authentication failed.]\nMongoNetworkError: failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect [MongoError: bad auth Authentication failed.]\n at Pool. (C:\Users\tedgo\node_modules\mongodb-core\lib\topologies\server.js:431:11)\n at Pool.emit (events.js:189:13)\n at connect (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\pool.js:557:14)\n at callback (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:109:5)\n at provider.auth.err (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:352:21)\n at _authenticateSingleConnection (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\auth_provider.js:66:11)\n at sendAuthCommand (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\scram.js:215:18)\n at Connection.messageHandler (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:334:5)\n at Connection.emit (events.js:189:13)\n at processMessage (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connection.js:364:10)\n at TLSSocket. (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connection.js:533:15)\n at TLSSocket.emit (events.js:189:13)\n at addChunk (_stream_readable.js:284:12)\n at readableAddChunk (_stream_readable.js:265:11)\n at TLSSocket.Readable.push (_stream_readable.js:220:10)\n at TLSWrap.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)","stack":"MongoNetworkError: failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect [MongoError: bad auth Authentication failed.]\n at Pool. (C:\Users\tedgo\node_modules\mongodb-core\lib\topologies\server.js:431:11)\n at Pool.emit (events.js:189:13)\n at connect (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\pool.js:557:14)\n at callback (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:109:5)\n at provider.auth.err (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:352:21)\n at _authenticateSingleConnection (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\auth_provider.js:66:11)\n at sendAuthCommand (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\sc
这个答案来自编码器 Santiago Beltram。
-几个问题。
--首先,default.config 文件需要保存在 custom-environmental-variable 中找到的所有变量。它没有。
--其次,在models.supporters.js中有一个错误,其中"require('jsonwebtoken')"被写成驼峰式"require('jasonWebToken')"。这不需要适当的程序。
--第三,并非所有依赖项都出现在 package.json 文件中。因此 heroku 不知道要包含它们。
在使用 --save 标志修复代码并在 package.json 中包含缺少的依赖项后,程序已成功部署到 heroku。