Error when starting node app via bash script - node.js

i have an node-app index.js at /home/pi/apps/index.js
my bash script: script.sh:
#!/usr/bin/env node
node /home/pi/apps/index.js
I want to use this bash script to run it as cron job but it already crashes when executing ./script.sh
ReferenceError: node is not defined
Thanks in advance

Related

cronjob to run shell script and execute npm command on raspberry pi (as opposed to calling node directly)

I am trying to build a shell script which can be called via a cronjob to trigger an npm nodejs application.
This is my start.sh shell script
#!/bin/bash
#!/usr/local/bin/npm
cd /home/lharby/sites/mysite
npm run start
If I cd to this folder and execute ./start.sh the command appears to run. (Path to bash and npm are both correct after checking which npm).
My cron job looks like this:
*/5 * * * * /home/lharby/sites/mysite/start.sh >> /home/lharby/sites/mysite/src/log/cron-errors.txt 2>&1
This is throwing an error and additionally I was lead to believe that using >> would append to the file, it seems to overwrite it each time.
My guess is that trying to run this command via cron it cannot access certain environment variables that are set up in my index.js
For example:
const config = {
access_token: process.env.NEXT_MASTODON_ACCESS_TOKEN,
client_key: process.env.NEXT_MASTODON_CLIENT_KEY,
client_secret: process.env.NEXT_MASTODON_CLIENT_SECRET,
timeout_ms: 60 * 1000,
api_url: 'https://botsin.space/api/v1/',
};
const M = new Mastodon(config);
I believe I see the same issue when I try to run node index.js from /home/sites/lharby/mysite/src/
As my package.json has this configuration:
"scripts": {
"start": "node ./src/index.js --experimental-modules",
"temp": "node ./src/temp.js --experimental-modules"
},
I was exploring looking at just trying to run the whole app passing in node index.js and passing in the argument flags but I need to be able to run the cron file invoking npm rather than node, as I guess that creates a wrapper and npm can access process.env variables.
From my cron-errors.txt file I am seeing this:
/home/lharby/sites/mysite/node_modules/mastodon-api/lib/mastodon.js:345
throw new Error('Mastodon config must include \'' + reqKey + '\' when using \'user_auth\'');
^
Error: Mastodon config must include 'access_token' when using 'user_auth'
at /home/lharby/sites/glyphbot/node_modules/mastodon-api/lib/mastodon.js:345:27
//
//
/home/lharby/sites/mysite/start.sh: line 4: npm: command not found
/bin/sh: 1: /home/sites/glyphbot/start.sh: not found
/bin/sh: 1: /home/sites/glyphbot/start.sh: not found
How can I ensure the crontab will invoke npm? I feel like I am doing everything correctly.
EDIT
My issues are:
How to run a node project using npm from a cron job?
Can the cronjob access environment variables from the npm command?
Should >> cron-errors.txt 2>&1 append the file rather than replace the content each time.
UPDATE 19.01.23
So I added exports for my variables to the .bashrc file. And when checking echo $NEXT_MASTODON_ACCESS_TOKEN I am seeing my string value.
Updated my .sh file so it now looks like this:
#!/bin/bash
node ./src/index.js --experimental-modules
And updated my cronjob to read this:
*/5 * * * * /home/lharby/sites/mysite/start.sh >> /home/lharby/sites/mysite/src/log/cron-errors.txt 2>&1
And I tried this also trying to bypass the shell script
*/5 * * * * /home/lharby/sites/mysite/src && /usr/local/bin/node index.js --experimental-modules >>/home/lharby/sites/mysite/src/log/cron-errors.txt 2>&1
It still failed with the same message being logged to the cron-errors.txt file.
However I am now able to run this command invoking node with argument flags (rather than using the npm command) So in the terminal I can type
node index.js --experimental-modules
As well as just running the .sh file I just don't understand why it is not passing this information to my cronjob.
I don't understand how if my code reads:
process.env.NEXT_MASTODON_ACCESS_TOKEN,
Will this get replaced or read by the bash export value instead?
Where are your environment variables being set up? It looks like your cron is at least running as expected, and your only problem is to get those env variables into the script correctly. My guess is that you need to use "export" (see bullet point 3)
I would debug this in a few different ways.
you should verify that it is the case that your index.js is not able to read your environment variables. I would recommend adding console.log(JSON.stringify(config, undefined, 2)) to check this.
you should verify that the SHELL has access to those variables before it runs the script. for this just run echo $NEXT_MASTODON_ACCESS_TOKEN (and similar for each variable) to verify if that is the case.
environment variables are a little funny. Assuming you set these values in your .bashrc with NEXT_MASTODON_ACCESS_TOKEN="whateverTheValueIs", just setting variables like this only affects your current process. In order for sub-processes to have the variable you need to export: export NEXT_MASTODON_ACCESS_TOKEN="insertValueHere"
Hope this helps!
Edit:
It's a little unclear what your current issues are, so it might be helpful if you bullet point each issue you are trying to solve

Bash script stuck after e2e tests run

I'm running my e2e tests with Nightwatch.js. I want them to run with a bash script (with the end result of them running in CI).
I am pretty new to bash and here is what i have so far:
#!/bin/bash
# exit on errors
set -e
export NODE_ENV=development
export LIVERELOAD_DISABLED=YES
npm install
NODE_ENV=e2e grunt build
echo "...Starting Node App"
#start app in the background
NODE_ENV=e2e node server.js &
#save node app process id
NODE_PROC=$!
#wait a bit
sleep 10
echo "...Running Frontend Tests"
NODE_ENV=e2e npm run nightwatch
echo "...Tests Finished... Killing Node App"
kill -9 $NODE_PROC
echo "...Node App Killed"
the problem is that the script gets stuck after running all the tests (line: NODE_ENV=e2e npm run nightwatch)
the only output i'm getting are the logs and the usual tests output. The script gets stuck no matter if the tests pass, fail, or some do and some don't.
I've tried adding exit 0 at the end which didn't work (makes sense, since it doesn't execute to that point).
Also, changing set -e to set -ex didn't change the output.
what am i missing here?
So i was looking in the wrong place, the script is completely fine, the issue was that i did not close the connection to the DB inside the tests.
Not sure why that caused the issue, but it fixed it

Basic upstart script to execute node.js script?

I'm trying to write a very basic upstart script that runs a node.js script when I enter 'service myscript start'.
Upstart:
description "my script"
author "barbra"
setuid ubuntu
env NODE=/usr/bin/nodejs
env NODE_PATH=/root/
script
cd $NODE_PATH
$NODE app.js
end script
However upstart isn't recognizing this as a service and generating this error:
"Unit myscript.service not found"
Am I missing anything in my upstart script?
UPDATE:
I've tried to check my upstart version using 'initctl version' and it replies:
"initctl: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused"

Bash script fails to run node on docker image

I have an app that I want to run on a single self contained Docker image.
I had it running fine on an Ubuntu based image, but the same script now causes me trouble on Alpine.
Here is my docker file :
FROM julienlengrand/alpine-node-rethinkdb
# Preparing
# RUN ln -snf /bin/bash /bin/sh
# # Define mountable directories.
VOLUME ["/data"]
# # Define working directory.
WORKDIR /data
# # Install app dependencies
COPY package.json /data
RUN npm install
# # Bundle app source
COPY . /data
# # Expose rethinkdb ports.
# - 8080: web UI
# - 28015: process
# - 29015: cluster
EXPOSE 8080
#EXPOSE 28015
#EXPOSE 29015
# Expose node app ports
EXPOSE 4567
CMD [ "/bin/sh", "/data/startApp.sh" ]
My startApp script is relatively simple :
#!/bin/sh
rethinkdb --bind all & sleep 1; node dbCreate.js; sleep 2; nohup node workers/worker.js & node app.js
But when I try to run it, I get the following error:
module.js:442
throw err;
^
'rror: Cannot find module '/data/app.js
at Function.Module._resolveFilename (module.js:440:15)
at Function.Module._load (module.js:388:25)
at Module.runMain (module.js:575:10)
at run (bootstrap_node.js:352:7)
at startup (bootstrap_node.js:144:9)
at bootstrap_node.js:467:3
This happens whether I run it automatically, or directly within the image using the shell.
I have checked and everything is correctly placed in the data folder.
Additionally, if I run all the commands one after the other directly in the sh shell everything runs as expected.
I have also tried to simplify my script as such :
#!/bin/sh
rethinkdb --bind all & sleep 1; node dbCreate.js; sleep 2; node app.js
bu the same issue happens.
Any idea what can go wrong? What could make my /data folder unavailable when running via the startApp script? Could it be that it is a specificity from Alpine?
Thanks,
The error message you are receiving looks like a classic carriage return issue as the quote after app.js has moved to the start of the line
'rror: Cannot find module '/data/app.js
Node should normally be able to deal with both line endings but shell scripts aren't so kind.
I generally default all projects/files/editors/git to a Unix \n unless there are specific requirements not too.
You can convert existing files with dos2unix or one of the answers in the question jlengrand found. I like perl -pi -e 's/\r\n/\n/g', because pie

How set upstart correctly for a node.js app

I am using an amazon ec2 instance with ubuntu to host my node.js application, i already made all the configurations, and is working good when i type:
nodemon ./bin/www
./bin/www is the file that creates the server.
Now, i am trying to setup the upstart, and i follow a tutorial, this is my configuration file:
path:
/etc/init/photogrid.conf:
inside:
description "Photogrid"
start on started mountall
stop on shutdown
respawn
respawn limit 99 5
env NODE_ENV=production
exec node /home/ubuntu/photogrid/bin/www >> /var/log/photogrid.log 2>&1
But when i try to access the site, is showing:
Cannot GET /
I follow a tutorial, and the only difference between my configuration file is this part:
Original:
exec node /home/ubuntu/photogrid/app.js >> /var/log/photogrid.log 2>&1
My one:
exec node /home/ubuntu/photogrid/bin/www >> /var/log/photogrid.log 2>&1
Start with upstart:
Start with nodemon bin/www:
In my logs i see the following when i try access the home '/':
^[[0mGET / ^[[33m404 ^[[0m12.036 ms - 13^[[0m
It seems that you need to switch to correct directory before launching exec. Maybe this will resolve your error:
description "Photogrid"
start on filesystem and started networking
stop on shutdown
respawn
respawn limit 99 5
env NODE_ENV=production
script
export HOME="/home/ubuntu/photogrid"
cd $HOME
exec node /home/ubuntu/photogrid/bin/www >> /var/log/photogrid.log 2>&1
end script
Try adding chdir /home/ubuntu/photogrid to your upstart config. Also, interactively in a terminal try: NODE_ENV=production nodemon ./bin/www. Perhaps you are using app.configure where you shouldn't be?

Resources