How can you execute a Node.js script via a cron job? - node.js

Quite simply, I have node script that I want to execute once a month.
30 6 1 * * node /home/steve/example/script.js
But this doesn't work, presumably because of path or the shell the command is being ran under. I've tried the following means of executing node via cron (tested with -v):
steve#atom:~$ node -v
v0.4.2
steve#atom:~$ sh node -v
sh: Can't open node
steve#atom:~$ bash node -v
/usr/local/bin/node: /usr/local/bin/node: cannot execute binary file
steve#atom:~$ /usr/local/bin/node -v
v0.4.2
steve#atom:~$ sh /usr/local/bin/node -v
/usr/local/bin/node: 1: Syntax error: "(" unexpected
steve#atom:~$ bash /usr/local/bin/node -v
/usr/local/bin/node: /usr/local/bin/node: cannot execute binary file
I've ran out of ideas to try, any advice?

just provide the full path to node /usr/local/bin/node in your cron job like:
30 6 1 * * /usr/local/bin/node /home/steve/example/script.js

These answers here saying using absolute path will all cause major problems for running a larger node app!
Real Complete Solution
Edit Cron Jobs
crontab -e
Find Node Path
which node
CD into the destination folder, then Change Cron Job according to Node Path and run script
*/2 * * * * cd /home/destination/path && /bin/node index.js
This will then allow you to run a full NodeJS application without all the errors like how using an absolute path for your index.js file.

Additionally, just put #!/usr/local/bin/node at the top of the script you want to execute. Then it will automatically know to execute the script with node. Make sure the file is executable as well.

You can also specify paths to binary files on top of your user crontab like:
PATH=/bin:/usr/bin:/usr/local/bin
* * * * * cd your/path && node foo.js
* * * * * cd your/path && npm run bar

in my laptop using Linux mint the given path not working so i used this to get a work around.
$ which node
$ /usr/bin/node
this worked for me.

This also works for user-level cron jobs
*/2 * * * * cd /home/destination/path && $(which node) index.js

I don't know if changing your relative paths in your script to absolute paths is a good idea
(what happens when your file system changes or you deploy in another environment?)
You could try wrapping it in a shell script, setting some environment variables in the crontab execution. (specifically PATH & NODE_PATH for starters)
Try my suggestion for this similar question:
https://stackoverflow.com/a/27823675/608269

NVM users:
Save the following script (say, cronjob.env.sh) anywhere at your PATH (let's say: $HOME/bin). Remember to make it executable (chmod +x). Replace 'username' with your user name as well:
#!/bin/bash
export NVM_DIR="/home/username/.nvm" #replace "username" with your user name
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
Edit cronjob:
crontab -e
Insert/edit your job:
0 0 * * * (. ~/bin/cronjob.env.sh; ~/bin/my-script-with-node-cmd.sh)
Calling node command (instead of some shell script), like the below job, works as well:
*/1 * * * * (. ~/bin/cronjob.env.sh; node ~/index.js)
PM2 users:
A different approach is using pm2, with --cron option, which accepts cron patterns (inside quotation marks):
pm2 start index.js --no-autorestart --cron "0 0 * * *"
--no-autorestart is for one-time scripts (otherwise, it will be restarted every time it is completed).

Use absolute paths for the node alias and the file to be run.
Edit Cron Jobs
crontab -e
Entry to Run Our Node File
This will run every minute.
*/1 * * * * * /bin/node /public/test.js
Full Tutorial
https://askmacgyver.com/blog/tutorial/how-to-run-node-scripts-from-a-cron-job

If you want to preserve the nvm functionality and allow your code to get an updated node version without needing to change the cron job info, put your job in a shell script that first sets up nvm, switches to proper node version, then runs the actual job. Here is an example for a project called invoicing that includes a cron script in its package.json.
File invoicing.sh:
#!/bin/bash
cd /home/produser/invoicing
export NVM_DIR="/home/produser/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
npm run cron
Then set this up as the command in your cron job listing:
0 16 1 * * produser /home/produser/invoicing/invoicing.sh
Now, if you change the node version in your project and update your .nvmrc with the proper version number and pull the new code onto the server, the next time the cron job runs it will run with version of node specified. Note that you must also make sure the server has the required node version.

Related

Why is cron not executing my node.js script properly?

I am trying to run a node.js script from cron. It is supposed to read a .json-File, make an API call and then write the response to a .json-File.
When executing manually everything works fine.
This does it's job
sudo node ~/bots/gtaa/index.js
sudo crontab -e
29 9 * * 1-5 /usr/bin/node ~/bots/gtaa/index.js >> ~/gtaa-bot.log 2>&1
grep cron /var/log/syslog
May 11 09:29:01 raspberrypi CRON[54381]: (root) CMD (/usr/bin/node ~/bots/gtaa/index.js >> ~/gtaa-bot.log 2>&1)
My index.js uses the local .env-File
require('dotenv').config({ path: __dirname + '/.env' })
There also is no gtaa-bot.log-File in the home directory.
A very similar question has been asked here but there are no useful answers provided.
Well I have experienced this issue, more recently using Ubuntu 20.04.4 LTS
Ultimately what ends up happening is cron runs in a different environment and most likely is unable to find the correct path to node.
There are some ways to configure this, however I found a much easier solution ended up being to just have cron execute a bash script, that runs nvm and/or node.
For example, I have this setup to run every 20 minutes:
20 * * * * /bin/bash/ /home/user/nvm_cron.sh
And in my nvm_cron.sh file:
# Load nvm
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm use 16.14.0
# Run node program
cd /home/user/folder && node start.js
Dont forget to make sure the nvm_cron.sh file is executable
This way I have control over the version of node that I want to run for the script, and don't have to worry about messing with cron.

Shell Script not executing, added to crontab

Here is my shell script, myscript.sh located in ~/bin
cd ../environment
. env/bin/activate
python3 office.py
The script office.py updates the database. I've tested and works with no issue. I used this command ./myscript.sh
Here is cronjob */5 * * * * cd ~/bin/myscript.sh added to crontab -e
When i check database, no changes. The cronjob isn't running? How do i solve?
You are not running the script but just trying to change directories, which will fail as myscript.sh is not a directory. You need to first cd ~/bin as you are using relative paths in your script and then run the script. Use this line:
*/5 * * * * cd ~/bin && ./myscript.sh
Also you may wanna check the syslog to check for cronjobs.
grep CRON /var/log/syslog
Have a look at this thread for more information on logging cronjobs.

Node JS run using Cron Job on AWS

I am trying to run a node script on an AWS Ubuntu server. When I log into the Ubuntu server from my terminal and run my script with the command "node dacDev.js" it works just fine. The script writes to a log file in another folder. I want to run this with a cron command on AWS, but it won't run. Here is what my cron job says.
"* * * * * /home/ubuntu/.nvm/versions/node/v13.14.0/bin/node /home/ubuntu/getmyteatime/cronjob.sh"
The file cronjob.sh contains the absolute path of the node script. It reads:
node /home/ubuntu/getmyteatime/dacDev.js
Nothing runs. What am I doing wrong?
For the node, you also need an absolute path to run any.js file. This is achievable but rather than running with node try to write a script and do the following:
echo $PATH # /path/to/env
which npm # /path/to/npm
Paste below lines when the command crontab -e is executed.
PATH=/path/to/env
* * * * * cd /path/to/app && path/to/npm run script >>/tmp/crontab.log 2>&1
>>/tmp/crontab.log 2>&1 -- means, it will log the result to this path for debugging purposes.

Crontab on shared hosting, not being started

Alright so I'm having an issue.
I've setup this correctly but something is out of order
I added this to my crontab
* * * * * /home/website/public_html/ && php artisan schedule:run >> /dev/null 2>&1
Now if I start this command from my terminal it will work, but on the crontab log I get this
/bin/sh: /home/website/public_html/ : is a directory
After the frequency of the execution (in your case five stars to run every minute) crontab syntax expects to find the command to run.
I guess you want change the working directory before running php, so you need to add cd to change directory:
cd /home/website/public_html/ && php artisan schedule:run
Anyway, there is plenty of examples and explanations about crontab in internet.

bash script doesn't work through crontab

I am running a bash script that transfers files to my AWS bucket.If i run the bash script through my terminal it works fine (via ./myBash.sh).
However I put it in my crontab but there it doesn't work.This is my bash script
#!/bin/bash
s3cmd put /home/anonymous/commLogs.txt s3://myBucket/
echo transfer completed
echo now listing files in the s3 bucket
s3cmd ls s3://myBucket/
echo check
And this is my crontab-
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
46 13 * * * /bin/bash myBash.sh
And here is a list of things i have aready tried -
1)tried running the crontab with a node app to test whether crontab was working(the answer was yes)
2)tried running the crontab without the SHELL and PATH
3)Tried running the bash script from cron using sudo (46 13 * * * sudo myBash.sh)
4)tried running the bash without the /bin/bash
5) Searched many sites on the net for an answer without satisfactory results
Can anyone help me with what the problem may be?(I am running Ubuntu 14.04)
After a long time getting the same error, I just did this :
SHELL=/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin
* * * * * /bin/bash /home/joaovitordeon/Documentos/test.sh
For anyone coming to this post.
I was having same problem and reason was crontab was running under root user and s3cmd was configured under ubuntu user.
so need to copy .s3cfg to root
cp -i /home/ubuntu/.s3cfg /root/.s3cfg

Resources