89

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?

MPelletier
  • 16,256
  • 15
  • 86
  • 137
Steve
  • 5,771
  • 4
  • 34
  • 49
  • 1
    Read this https://github.com/wahengchang/nodejs-cron-job-must-know ('nodejs-cron-job-must-know' section). It is needed to navigate to the directory where script is located using `cd` command. I tried maybe everything but only after this it started to work. – Chaki_Black Apr 24 '19 at 12:43

10 Answers10

130

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
Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • 7
    It turned out to be a couple of problems, the full path as you said fixed the cron, but relative paths in the script were also a issue. – Steve May 01 '11 at 16:58
  • @Steve how did you fix the relative path issues? – codecowboy Feb 01 '14 at 09:48
  • @Steve I'm using the config module (e.g. require('config').DB) and when running via crontab, the config variables are not populated. – codecowboy Feb 01 '14 at 10:24
  • 29
    WARNING! If you were using nvm or n to manage your node installs - putting `/usr/local/bin/node` - may not work! In order to obtain the actual path to node, use `which node` - then put that path before your script. E.G. I am using node 0.10.32 from nvm, so my path to node is: `/home/username/.nvm/v0.10.32/bin/node` – YemSalat Jun 07 '15 at 03:38
  • 1
    @YemSalat It is better to declare that in a node version indepentdent way: # doc Required to enable node/nvm for a cronjob () # doc cron uses by default a short PATH = /usr/bin:/bin and does not execute /root/.bashrc (equal to /root/.bashrc) # doc nvm (node version manager) does not configure itself in a crontab job (that is only done for interactive shells in my /root/.bashrc). export NVM_DIR="/root/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm – Rolf Dec 09 '16 at 09:41
  • is this problem just node-specific or do I always need to add the path to the program? – hardfork Jan 03 '19 at 19:41
  • I'm still getting module not found , but I can run it well when I cd into it – CodeGuru Nov 04 '19 at 01:39
  • 1
    Thanks! [Here's an example](https://gist.github.com/simov/cdbebe2d65644279db1323042fcf7624) if you want to integrate nvm too – ifthenelse Apr 25 '21 at 16:06
60

These answers here saying using absolute path will all cause major problems for running a larger node app!

Real Complete Solution

Find Node Path

which node

Edit Cron Jobs

crontab -e

Set your Change Cron Job to CD into the destination folder, call Node Path by it's full 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.

cmcculloh
  • 47,596
  • 40
  • 105
  • 130
Curtis Xiao
  • 701
  • 6
  • 3
  • 1
    Thanks for the correct answer, I tried the most voted solution but my script didn't work, then I tried other solutions, lig node-cron, but your solution works, is simple and easy to understand! – carmolim Nov 12 '20 at 18:24
  • 1
    This was the perfect answer for me too, thank you! – Smlok Feb 18 '21 at 23:47
  • This one actually works for me as well. Thanks man. – Rajan Twanabashu Apr 04 '21 at 14:19
  • This should be marked as answer. Thanks mate! – Jestin Sep 30 '21 at 05:10
  • This was killing me. Thank you! Also a note to people after. For me the confusion was that Cron on Ubuntu is operating as root, even if you aren't editing it as such. Make sure your paths are absolute from the root, not just from your profile. – isshakes Jan 10 '22 at 22:56
  • This solution works fine! Solved the problem for me. Thanks. – Luiz Aug 22 '22 at 22:18
  • Thanks. This answer is not just work but showing how to find where node is, and how to edit crontab. Very well. – vee Jun 06 '23 at 21:26
30

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.

We Are All Monica
  • 13,000
  • 8
  • 46
  • 72
Mauvis Ledford
  • 40,827
  • 17
  • 81
  • 86
13

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
imbolc
  • 1,620
  • 1
  • 19
  • 32
8

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.

zabusa
  • 2,520
  • 21
  • 25
6

This also works for user-level cron jobs

 */2 * * * * cd /home/destination/path && $(which node) index.js
OlaoluwaM
  • 71
  • 1
  • 2
4

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

Community
  • 1
  • 1
Marc Smith
  • 1,111
  • 10
  • 18
3

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).

l30.4l3x
  • 365
  • 1
  • 4
  • 6
0

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

Eswar Rajesh Pinapala
  • 4,841
  • 4
  • 32
  • 40
Timothy Moody
  • 479
  • 1
  • 7
  • 9
0

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.

Chris Edgington
  • 1,208
  • 12
  • 11