I'm connecting to mongodb (on a Ubuntu machine) from a js script; when I execute the command from command line (node <name of the script>
) everything works just fine but when I execute the same command from cron the connection times out:
const mongodb = require("mongodb").MongoClient;
const env = require("dotenv").config({
path: "../.env",
}).parsed;
async function dbConnection() {
let url = env.DB_URL;
console.log("DB_URL", url); // This correctly prints the url both when executing as cron or simply from command line
// Mongo options
let opts = {
useNewUrlParser: true,
useUnifiedTopology: true
};
try {
return mongodb.connect(url, opts);
} catch (err) {
throw err;
}
}
async function DataLoading() {
try {
let dbInstance;
try {
dbInstance = await dbConnection()
if(!dbInstance)
throw "DB connection failed"
} catch (err) {
errors.push({
date: new Date().toISOString(),
error: err,
location: "Db connection"
});
}
console.log("Time elapsed: " + (new Date() - time) )
// On cron dbInstance is undefined, causing an error, on command line it's what's supposed to
let dbStocks = dbInstance.db(env.DB_NAME).collection("stocks")
Time elapsed console log is somewhere near 30 seconds when executed as cron, few hundreds ms when from command line.
Note: When I say command line I'm referring to server's command line (mongo is on localhost), not my remote personal computer.
My cron is:
00 22 * * 1-5 cd /path/to/scripts/folder && node script.js >> cronErrors.txt
###UPDATE###
For some reason, by using public url connection string (so mongodb://usr:pwd@my-domain:27017 instead of mongodb://usr:pwd@localhost:27017) it works and since I'm using TLS connection and I don't see any latency issue it's ok, might be a better idea to use node-cron library; My mongod.conf file is:
# network interfaces
net:
bindIp: 127.0.0.1, 127.0.0.2, <my-domain.com>, localhost
port: 27017
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongo.pem
# how the process runs
processManagement:
timeZoneInfo: /usr/share/zoneinfo
security:
authorization: 'enabled'
Without more specific information, I can only take a stab in the dark, but...
This is likely due to missing environment variables. You'll need to manually setup the environment for the script in the crontab itself, or have your script directly load configured values from a file (or another source).
e.g
Cron jobs are executed in a non-interactive, non-login shell. They do not source default shell startup scripts - e.g.
~/.bashrc
and~/.bash_profile
- They do not have access to the environment variables set via those scripts (including$PATH
) or to ones you set during your current terminal session.There are many methods for configuring cron jobs. Which one you end up using depends on your particular environment, current task, best-practices and personal preference.
Some useful references: