Start app as root with pm2 - node.js

I have a daemon that must be run as root on startup.
I use pm2 to start other apps but can not figure out if it can start an app as root. Can it be done?
If not, what are my options?

I had problems with sudo pm2 start api, but this was since pm2 was already running without sudo privileges, therefor you need to run:
pm2 kill
sudo pm2 start api
This kills the pm2 deamon first, so that it starts in sudo, but then you need sudo for ALL pm2 commands afterwards, like: sudo pm2 ls

If you only need your daemon to be run as root in order to access a port number (such as 80 or 443), the pm2 documentation recommends using authbind. So, if you want the user yourusername to have access to port 80, run:
$ sudo apt-get install authbind
$ sudo touch /etc/authbind/byport/80
$ sudo chown yourusername /etc/authbind/byport/80
$ sudo chmod 755 /etc/authbind/byport/80
$ authbind --deep pm2 update
And then use authbind --deep pm2 instead of pm2. The documentation suggests setting up an alias.

I would recommend:
sudo pm2 start index.js
OR
pm2 start 'http-server' /var/www -p 80
sudo pm2 startup
pm2 save
OR
pm2 start 'which http-server' /var/www -p 80
To start it on your HTTP Port
Also, I always put -i 0 at the end - this starts up as many worker processes as you have cores. Check THIS
It is not always necessary to start PM2 as root. If you have PM2 as root and the cli module installed, security is a big risk. This is only required if you're starting your app on a port between 1 and 1024

Wasted about an hour
On AWS EC2 machine, one system was in inconsistent state due to earlier installations, that forced sudo elevations in the application for all commands to OS, like sh, etc.
pm2 was running as root:
ps aux | grep pm2
# root ... PM2 v4.1.2: God Daemon (/root/.pm2)
Now pm2 is running as ubuntu:
ps aux | grep pm2
# ubuntu ... PM2 v4.1.2: God Daemon (/home/ubuntu/.pm2)
Below commands worked:
sudo pm2 kill
sudo npm remove pm2 -g
sudo npm i -g pm2#latest
sudo pm2 update
sudo chown -R ubuntu:ubuntu /home/ubuntu/.pm2
Hope that helps

You should start pm2 as a root, (sudo pm2 start app.js), then your app will start as a root

First, install pm2 globally.
Then set root permissions to pm2 using this command
sudo chown ubuntu:ubuntu /home/ubuntu/.pm2/rpc.sock /home/ubuntu/.pm2/pub.sock

you might consider routing your traffic with iptables, since there is a reason behind this errror
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000

Related

Run node js on ports 80 without running as root

i want to run my node.js application on port 80 without running it as root
$> which node
/usr/bin/node
I have tried to use setcap but it's not working:
$> sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/node
Failed to set capabilities on file `/usr/bin/node' (Operation not
permitted)
The value of the capability argument is not permitted for a file. Or
the file is not a regular (non-symlink) file
What am i doing wrong ?
Ports below 1000 require sudo privilege. You can use the following command to allow it to bind to port 80 without sudo:
sudo setcap 'cap_net_bind_service=+ep' `which node`
Finally, I have used port redirection, not with iptables but with ufw
https://serverfault.com/questions/238563/can-i-use-ufw-to-setup-a-port-forward

pm2 doesn't startup in ubuntu

I am trying to run pm2 at startup without success..
I am installing in ubuntu 16.04.
My npm directory is in : ~/.npm-global.
There, I can see pm2 -> ../lib/node_modules/pm2/bin/pm2
There is no dump file.
My pm2 directory is ~/.pm2:
There , I can see dump.pm2 and rpc.sock
If I do:
sudo $(which pm2) start app.js
sudo $(which pm2) startup ubuntu -u $USER
sudo $(which pm2) save
it shows me :
Generating system init script in /etc/init.d/pm2-init.sh
[PM2] Making script booting at startup...
[PM2] -ubuntu- Using the command:
su -c "chmod +x /etc/init.d/pm2-init.sh && update-rc.d pm2-init.sh defaults"
[PM2] Done.
[PM2] Saving current process list...
[PM2] Successfully saved in /home/theUser/.pm2/dump.pm2
and I can see that the app is running fine.
If I do though, sudo ~/.npm-global/bin/pm2 start /etc/init.d/pm2-init.sh,it gives me:
events.js:160
throw er; // Unhandled 'error' event
^
Error: connect EACCES ~/.pm2/rpc.sock
at ....
The /etc/init.d/pm2-init.sh has :
NAME=pm2
PM2=/home/theUser/.pm2
USER=theUser
DEFAULT=/etc/default/$NAME
export PATH=/usr/bin:$PATH
export PM2_HOME="/home/theUser/.npm-global/lib/node_modules/pm2/bin/"
I tried also using : export PM2_HOME="/home/theUser/.pm2
and when I start the scipt from /etc/init.d/pm2-init.sh , it says that it cannot dump ( probably because dump exists only in ~/.pm2 directory )
If I try:
sudo $(which pm2) start app.js
sudo $(which pm2) startup systemd -u $USER
sudo $(which pm2) save
and execute manually ( because it can't find pm2 as normal user ) :
sudo ~/.npm-global/pm2 dump && ~/.npm-global/pm2 kill && systemctl daemon-reload && systemctl enable ~/.npm-global/pm2 && systemctl start ~/.npm-global/pm2
So,
1) I am not sure if I have to run sudo $(which pm2) startup systemd -u $USER or sudo $(which pm2) startup ubuntu -u $USER
2) What PM2 and PM2_HOME should I have?
3) How can I add ~/.npm-global/bin to sudo path ,or generally how to be able to use this path when I run pm2 as sudo.Note, that I don't want to alter /etc/sudoers.
I can't answer all your questions, but I had the same problem and this worked for me:
http://www.anicehumble.com/2016/05/pm2-must-not-be-ran-with-sudo.html

How to run pm2 so other server users are able to access the process?

When I start my Nodejs app with pm2, other server users are not able to access the process.
Even if I start pm2 from a custom directory (not current user's ~/, what pm2 is using by default):
HOME=/var/www pm2 start app.js
Directory is accessible by any user (comparing to ~/, but there's still no way other server user is able to access the process.
When other server user does pm2 list, it shows him 0 processes are running – but there are (started by another user). And when other user tries HOME=/var/www pm2 list, CLI throws an error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: connect EACCES
at errnoException (net.js:905:11)
at Object.afterConnect [as oncomplete] (net.js:896:19)
So I am wondering how to make sure users are able to access pm2 processes run by other server users? Or it shall be approached differently?
I am wondering why every server user is able to make git pull to deploy latest source code from a Git repository, but can't restart pm2 process afterwards? Only the user that started pm2 process is able to restart it… Weird.
Here's how we bypassed this.
Just create a group
Create a new group pm2 or whatever name works for you
$ groupadd pm2
Change the /var/www/ folder group owner to group pm2
$ chgrp -R pm2 /var/www
Add the other user, let's say bob, to pm2
$ usermod -aG pm2 bob
Now bob can run pm2 commands by changing $HOME to /var/www
$ env HOME=/var/www pm2 list
Or (better still) create an alias as #jcollum suggested
$ alias pm2='env HOME=/var/www pm2'
Ok, here is my solution for same problem:
# 1. Create user PM2 and set his password
sudo useradd -d /opt/pm2 -m -s /bin/bash pm2
sudo passwd pm2
# 2. Add users you want to provide the access to PM2 to PM2 group
sudo usermod -aG pm2 <username>
# Note: if you added yourself to pm2 group, perform logout and login back to the host machine
# 3. Set the PM2_HOME variable
sudo touch /etc/profile.d/pm2.sh
sudo sh -c 'echo "export PM2_HOME=\"/opt/pm2/.pm2\"" > /etc/profile.d/pm2.sh'
source /etc/profile.d/pm2.sh
# 4. Install the PM2
# Check the npm prefix if fail:
# https://docs.npmjs.com/misc/config#prefix
sudo npm install pm2 -g
# 5. Make startup script
sudo pm2 startup ubuntu -u pm2 --hp /opt/pm2
sudo systemctl enable pm2-pm2 && \
sudo systemctl start pm2-pm2 && \
sudo systemctl status pm2-pm2
# 6. Change permission of PM2_HOME
sudo chmod -v g+w /opt/pm2/.pm2
# 7. Check the PM2
pm2 status
It seems that PM2 saves data under user's '~/.pm2' folder, so other users can not see your PM2 process with 'pm2 status'.
I created a new linux user for PM2, and all users use 'su pm2user' before starting Pm2 process:
$ sudo su pm2user
$ sudo pm2 start app.js
It's a stupid way, but it is simple and works well. Hope this would help :)
Assuming you run pm2 as www-data. To have access to that pm2 instance, I do: sudo -u www-data HOME=/var/www pm2 list for example. You can, of course, create a script (e.g. supm2) that does that for you so you can just do supm2 list instead.
I've faced a similar issue. The reason may be that you do not have the required permissions, or you do not own the pid and sock files created by pm2. In my case, it was working fine when I started the pm2 from commandline instead of startup. When I used startup, it was running as root user by default. So root was the owner of the pid, sock files
I know that I am late to the party, but this is how I did it:
PM2="/usr/share/nodejs/pm2"
USER="me"
useradd $USER
groupadd pm2
chgrp -R pm2 $PM2
usermod -aG pm2 $USER
setfacl -Rdm g:pm2:rwx $PM2
/etc/bash.bashrc etc
export PM2_HOME=$PM2;
I also have the need to use pm2 with multiple users and I found a solution seemed even better. Here is brief version from Piotr Sobuś's medium article.
sudo groupadd pm2 # Create pm2 group for user who want manage pm2 together
sudo usermod -a -G pm2 user1 # add yourself to pm2 group
sudo usermod -a -G pm2 user2 # add as many user as you need to pm2 group
# you need to login again for new group to apply to user
sudo mkdir /etc/pm2daemon
sudo chgrp -R pm2 /etc/pm2daemon
sudo chmod -R 770 /etc/pm2daemon
sudo chmod g+s /etc/pm2daemon
Add following lines to ~/.bashrc for users that you want to share pm2 management.
# PM2 environment
export PM2_HOME=/etc/pm2daemon
If you install pm2 systemd service with pm2 startup. You also need to modify PIDFILE and PM2_HOME in systemd service confgiuration file:
/etc/systemd/system/multi-user.target.wants/pm2-YOUR_USER_NAME.service
from:
...
Environment=PM2_HOME=/home/YOUR_USER_NAME/.pm2
PIDFile=/home/YOUR_USER_NAME/.pm2/pm2.pid
...
to:
...
Environment=PM2_HOME=/etc/pm2daemon
PIDFile=/etc/pm2daemon/pm2.pid
...
After modification, you need to use systemctl daemon-reload to update systemd configuration. Now start the service with sudo systemctl start pm2-YOUR_USER_NAME.service.
Then you can now use pm2 across users that you shared.
PS. If you fail to start service with systemctl, kill current pm2 daemon process by pm2 kill. Now you should able to use systemctl to start pm2 daemon.

Running NodeJs http-server forever with PM2

My question is about running HTTP-server in combination with PM2.
The problem I face is that:
HTTP-server requires as input a folder which is the root of the website and a port number to run the website on.
PM2 doesn't recognize the HTTP-server command, even when HTTP-server is installed with the -g option.
So I tried the following (note the double dash which should pass the parameters to the HTTP-server script:
/node_modules/http-server/lib$ pm2 start http-server.js -- /home/unixuser/websiteroot -p8686
But it doesn't work.
I also tried:
http-server /home/unixuser/websiteroot -p8686
Which does work, but doesn't have the great support of pm2 ?
Any suggestions would be great, thanks!
You almost had it.
Check where http-server is located by executing:
$ which http-server
You should get something like this /usr/bin/http-server
Then cd to the directory you want to serve files from and execute:
$ pm2 start /usr/bin/http-server --name my-file-server -- -p 8080 -d false
--name my-file-server is optional, but -- is required to pass arguments through to the http-server command.
pm2 start <location>/http-server --name http-server -- -p <port> -d false
or
PM2 modules it self has in-build static file to be served, which is similar to http-server
https://pm2.keymetrics.io/docs/usage/expose/
pm2 serve <path> <port>
pm2 start 'http-server-spa websiteroot index.html 8080'
if we have a build generated by grunt,then go to its path and hit:
~/app/build/prod$ sudo pm2 start /usr/local/bin/http-server -p 8080
Now check app status at localhost:8080

How NodeJS server running for ever

I use Putty.
When I start server with "node X.js", putty start server running.
If I exit from putty the server stop.
How I can keep it running and make it default running after restart or reboot the server (computer)?
I have centos 5.10.
Thank you!
I use pm2 to do it
To install pm2
sudo npm install -g pm2
To generate startup script
pm2 startup ubuntu(centos in your case)
Then pm2 will prompt the command for you to run, in my case, it is like
PM2 You have to run this command as root
PM2 Execute the following command :
PM2 sudo env PATH=$PATH:/usr/bin pm2 startup ubuntu -u USERNAME
Then you could run
sudo env PATH=$PATH:/usr/bin pm2 startup ubuntu -u USERNAME
Then you could see
PM2 Generating system init script in /etc/init.d/pm2-init.sh
PM2 Making script booting at startup...
PM2 -ubuntu- Using the command su -c "chmod +x /etc/init.d/pm2-init.sh && update-rc.d pm2-init.sh defaults"
Adding system startup for /etc/init.d/pm2-init.sh ...
/etc/rc0.d/K20pm2-init.sh -> ../init.d/pm2-init.sh
/etc/rc1.d/K20pm2-init.sh -> ../init.d/pm2-init.sh
/etc/rc6.d/K20pm2-init.sh -> ../init.d/pm2-init.sh
/etc/rc2.d/S20pm2-init.sh -> ../init.d/pm2-init.sh
/etc/rc3.d/S20pm2-init.sh -> ../init.d/pm2-init.sh
/etc/rc4.d/S20pm2-init.sh -> ../init.d/pm2-init.sh
/etc/rc5.d/S20pm2-init.sh -> ../init.d/pm2-init.sh
PM2 Done.
Once you have started the apps and want to keep them on server reboot do:
pm2 save
You can refer to Startup script section in https://github.com/Unitech/pm2#startup-script
There are several ways, I personally like forever.
sudo npm install -g forever
forever start app.js &
note that ending with & will fork the process to background.
You can later check the process with
forever list
To run it when your system restarts you can add to cron
#reboot forever start app.js &> /dev/null
Remember to point to the absolute location of app.js

Resources