Nodejs: Bash can't find node? - bash

#!/bin/sh
exec node /opt/nodejs/first/app.js 1>>/opt/nodejs/first/log/output 2>>/opt/nodejs/first/log/error
This shell script throws an error:
exec: 2: node: not found
I'm trying to launch it on system boot:
sudo update-rc.d autostart.sh defaults 95
I'm doing something wrong?
Maybe boot level is wrong or order number, or something else?
Thanks ;)

You need to set your PATH environment variable to include the directory where your node binary lives. For starting on boot, what OS are you running? I suggest Ubuntu where you can use the upstart system. Here's a simple upstart script to make a node server work as a daemon.
description "start and stop your node.js server"
version "1.0"
author "You <you#yoursite.example>"
start on startup
respawn
env NODE_ENV=production
env PATH=/path/to/node/bin
chdir /path/to/your/app/root
exec su -c 'node app/server.js' www-data >> var/log/stdout.log 2>&1

I don't know node, but the typical error here is that the PATH variable at the time of execution of the script does not contain the path to your program. The easiest fix is to simply use the full path:
#!/bin/bash
exec /path/to/node ...

Related

(shell script file) pm2: command not found in crontab task

my shell script
#!/bin/bash
pm2 start server.js
my crontab task
* * * * * /home/ec2-user/abcd/test.sh > /home/ec2-user/cron.log 2>&1
What I got from the log:
home/ec2-user/abcd/test.sh: line 2: pm2: command not found
how to fix it?
Remark:
1.When I execute ./test.sh, it runs normally
2.which pm2 - shows
~/.nvm/versions/node/v14.16.1/bin/pm2
The problem may be because of that PATH environment variable hasn't been set when the cron job is being executed and this is why your shell script can't find pm2. You have to enter the complete address of pm2.
Example if pm2 is in /usr/bin/:
#!/bin/bash
/usr/bin/pm2 start server.js
Or you may want to just set PATH env before the command you want to execute in you shell script.
In normal, when you execute the program in you terminal, the environment variables are set properly. This is why you can run your shell script in your terminal without any problem.
Set the path command like mentioned in the other answer.
PATH="/usr/bin:/bin:/home/ec2-user/.nvm/versions/node/v14.16.1/bin"
Next, locate the path to your server.js file and add the pm2 start command with the path.
pm2 start /home/ec2-user/ .....your path to the file..... /server.js
Complete code:
#!/bin/bash
PATH="/usr/bin:/bin:/home/ec2-user/.nvm/versions/node/v14.16.1/bin"
pm2 start /home/ec2-user/ .....your path to the file..... /server.js

PM2 startup on macOS Catalina

I'm trying to set pm2 to auto start on Mac OS like this pm2 startup
However I keep getting this error:
env: Fusion.app/Contents/Public:/usr/local/bin: No such file or directory
I tried the suggestion from this page: How to use pm2 startup command on Mac? But the even using this command I keep getting the same error: pm2 startup darwin
How can I get pm2 to startup automatically on Mac OS Catalina?
Thanks!
When you run pm2 startup command it suggests you PATH variable. It seems that this variable contains spaces that causes this error. Try to get rid of Fusion.app part of it.
Expanding on zored's answer, what's probably happening is that pm2 isn't generating the correct script because your PATH variable contains spaces (most likely "VMWare Fusion" in your case).
Run echo $PATH, clean it up by escaping the space character using a backslash (\), then manually paste the resulting PATH variable in pm2's generated startup script.
So basically instead of running a generated pm2 script like this:
sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup launchd -u <user> --hp <user_folder>
run something like this:
sudo env PATH=<your `echo $PATH` output with escaped spaces>:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup launchd -u <user> --hp <user_folder>
In case you wonder where the VMWare path parameter is set (and could be changed permanently):
/etc/paths.d/com.vmware.fusion.public
The content of this file is added to the PATH environment

Run an shell script on startup (not login) on Ubuntu 14.04

I have a build server. I'm using the Azure Build Agent script. It's a shell script that will run continuously while the server is up. Problem is that I cannot seem to get it to run on startup. I've tried /etc/init.d and /etc/rc.local and the agent is not being run. Nothing concerning the build agent in the boot logs.
For /etc/init.d I created the script agent.sh which contains:
#!/bin/bash
sh ~/agent/run.sh
Gave it the proper permissions chmod 755 agent.shand moved it to /etc/init.d.
and for /etc/rc.local, I just appended the following
sh ~/agent/run.sh &
before exit 0.
What am I doing wrong?
EDIT: added examples.
EDIT 2: Just noticed that the init.d README says that shell scripts need to start with #!/bin/sh and not #!/bin/bash. Also used absolute path, but no change.
FINAL EDIT: As #ewrammer suggested, I used cron and it worked. crontab -e and then #reboot /home/user/agent/run.sh.
It is hard to see what is wrong if you are not posting what you have done, but why not add it as a cron job with #reboot as pattern? Then cron will run the script every time the computer starts.
Just in case, using a supervisor could be a good idea, In Ubuntu 14 you don't have systemd but you can choose from others https://en.wikipedia.org/wiki/Process_supervision.
If using immortal, after installing it, you just need to create a run.yml file in /etc/immortal with something like:
cmd: /path/to/command
log:
file: /var/log/command.log
This will start your script/command on every start, besides ensuring your script/app is always up and running.

Commands to execute background process in Docker CMD

I am creating a docker image using a Dockerfile. I would like to execute some scripts while starting the docker container. Currently I have a shell script to execute all the necessary processes
CMD ["sh","start.sh"]
I would like to execute a shell command with a process running in background example
CMD ["sh", "-c", "mongod --dbpath /test &"]
Besides the comments on your question that already pointed out a few things about Docker best practices you could anyway start a background process from within your start.sh script and keep that start.sh script itself in foreground using the nohup command and the ampersand (&). I did not try it with mongod but something like the following in your start.sh script could work:
#!/bin/sh
...
nohup sh -c mongod --dbpath /test &
...
Of course there is also the official Docker documentation of how to start multiple services, again using a script file not the CMD. The docker documentation also states how to use supervisord as a process manager:
FROM ubuntu:latest
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ["/usr/bin/supervisord"]
If it is an option you could use a phusion base images which allows running multiple processes in one container. Thus you can run system services such as cron or other processes using a service supervisor like runit.
More information about whether or not a phusion base image is a good choice in your use case can be found here
A ruby focused description of how to avoid running more processes in your container except for your app you can find here. The elaborations are too detailed to repeat on SO.

Launching a bash script on boot on OS X

UPDATE:
The proposed link was the solution to this question. On a Mac you have to make symlink:
sudo ln -s /usr/local/bin/node /usr/bin/node
I wanted to automate some processes on boot of a mac mini.
The script should fire up some node.js scripts (forever). The script itself is fired by a launchd process. I have several scripts that work like that. But that one I have a problem:
#!/bin/bash
export PATH=/usr/local/bin
export NODE_ENV=production
cd /Volumes/Services/Proxy
forever -a start /Volumes/Services/Proxy/app.js
This script works pretty fine if executed in the terminal. It makes what it does.
But this script throws errors on std.err when launched on boot.
env: node: no such file or directory
First I thought it's a problem because the PATH to "forever" ist not known on startup so I added the export PATH explicitly.
It throws the same error when I give the absolute path to "forever":
#!/bin/bash
export NODE_ENV=production
cd /Volumes/Services/Proxy
/usr/local/bin/forever -a start /Volumes/Services/Proxy/app.js
There is no error in the launched.plist file. If I add other content to this script like for example mkdir FOO it does this without problems.
... im not so firm with shell scripting... :(
Anyone knows what I'm doin wrong?

Resources