How do I automatically start a node/express app (with pm2), having node installed using software collections (scl), on CentOS7 - node.js

1. Summarize the problem
I would like for a node/express app.js to listen on a port 3000, on container startup.
I created a CentOS 7 Docker container, installed the software collections (SCL) repo, and then installed node.
I can now enable node with:
scl enable rh-nodejs10 bash, and so I did, and then installed express (globally), and pm2 (globally), and can successfully run a minimal express app listening on port 3000 with commands I run at the command line.
I put scl enable rh-nodejs10 bash in my .bash_profile (of a user I created named: www - because I do not want root running the web server).
In fact, I will be building a rootless container (buildah), next after this, so there will be no 'root' user at all for security concerns.
Now on container startup I want to have the web server start automatically, and be able to get a response from: http://localhost:3000 (hello world).
The problem is that on container startup, node is not enabled for any user until a shell is invoked to enable it.
2. Provide background including what you've already tried
I have searched the web for a solution of using node, express, pm2 in conjunction with CentOS 7 software collections and have found no solution.
Please only reply if you have actually tried the solution your recommend, and have it working, otherwise it most likely will not work.
systemd needs to:
1. enable node
2. run pm2 start app
I tried putting both in a shell, but when you enable node, you are then put in a sub-shell and cannot script any additional commands.
3. show some code
scl enable rh-nodejs10 bash
4. Describe expected and actual results including any error messages
I expect the node/express server to listen on port 3000 on container startup.

I have node running on reboot on RHEL 7 by using scl-utils/scl_source technique found here
$ cat /etc/profile.d/enablenodejs.sh
#!/bin/bash
source scl_source enable rh-nodejs10

Related

Is there any way to manage node.js server from web interface?

I am in need to manage my node server without entering into server console. I have tried using forever, nodemon and pm2 npms. Whenever, I need to start or stop the node application, I need to connect the server via terminal. I want to avoid that and willing to see the possibility if that can be managed through any web interface or any browser plugin/extension.
Already tried forever, nodemon and pm2
You can use npm pm2-gui install it by this command npm i pm2-gui
See the docs and guides from here https://www.npmjs.com/package/pm2-gui
I started looking for some GUI and Web interface of PM2. Tried several npms but "mc-pm2-web" worked really good for me.
I am using Node via NVM and my node version was v10.15.3. Installed this https://www.npmjs.com/package/mc-pm2-web and it was straight forward what I was actually looking for.
Here's are the step if anybody wants to install and configure "mc-pm2-web" in AWS EC2.
I am using Amazon Linux
I am using NVM and running v10.15.3
Already had NGINX & PHP-FPM running on server using port 9000
pm2 already installed
Visit this link:
https://www.npmjs.com/package/mc-pm2-web
npm install -g pm2-web
pm2-web
If you encountered any error then you may check your config.json file. In my case the config file path was:
/home/ec2-user/.nvm/versions/node/v10.15.3/bin/pm2-web/config.json
I made following changes in config file to make it working:
Port from 9000 to 9010 because 9000 was being used by PHP-FPM
Changed the host name from "localhost" to "my-domain" which was already hosted in NGINX
Enabled authentication and set the Username and Password for making it secure
Allowed 9010 port from AWS EC2 firewall / security group of that instance
Added pm2-web in pm2 by executing "pm2 start pm2-web" command

Configure the npm to start in the background on Mac OS X

Description
I am on a Mac OS X.
Right now, I have almost 10 Laravel/LAMP projects locally, that I ran using vhost configured with Apache. The awesome part about them is even when I restart my Mac or move between networks, or even close the terminal app/tab of my projects, the Apache is still running, all my local sites will still be accessible.
Goal
Now, I am looking to do the same things with my MEAN apps.
How would one configure something like that ?
Let's say I have 3 MEAN apps.
Example
App1
FE running on port : http://localhost:4201
BE running on port : http://localhost:3001
App2
FE running on port : http://localhost:4202
BE running on port : http://localhost:3002
App3
FE running on port : http://localhost:4203
BE running on port : http://localhost:3003
I'm opening for anything suggestions at this moment.
Can we configure the npm to start in the background ?
BE/API
FE
You can use macOS's launchd to run services in the background. There are a couple good GUI apps that make it easier to create launch services:
LaunchControl ($10)
Lingon ($10) - If you go with Lingon, get Lingon X 5 from the official website instead of Lingon 3 from the Mac App Store; Lingon X 5 is more powerful because it is not limited by Apple's sandboxing.
There's also launched.zerowidth.com, an interactive online tool for creating the .plist files that launchd uses.
launchd.info is also a good resource if you want to set them up manually. Apple's documentation is available too.
If you are having problems with commands not working, I recommend trying these troubleshooting steps:
Convert all your commands to use absolute paths (e.g. npm -> /usr/local/bin/npm). You can find the absolute path of a command by running which with the name of the command (e.g. which npm)
Run your commands from within bash using /bin/bash -c (e.g /bin/bash -c "/usr/local/bin/npm start")
One thing you can do is dockerize your applications.
With docker you can run your applications in a light weight virtual machine known as containers in your computer.
This have some advantages, for example, you can run your app with port 80 inside the virtual machine and expose another port to your machine. You can start or stop the container and so forth.
Go to https://www.docker.com/what-docker for more information.

How do I leave Node.js server on EC2 running forever?

As you can tell by my question, I'm new to this...
I built my first website, I set up my first Node.js server to serve it and then pushed everything live on EC2.
I tested everything on my EC2 IP address and everything seems to be working.
Now up until now, I've been testing my app locally so it makes sense that whenever I closed the terminal, app.js would stop running so nothing would be served on localhost.
Now that my server is on EC2, the same thing happens ("obviously" one could say..) whenever I close my terminal.
So my question is how do I keep my Node.js server running on EC2 for like... forever..so that my site stays live.. forever :)
I read something about a node module called "forever" but I'm wondering (being new and all..) why isn't this "forever" functionality a default setting of the Node.js-EC2 system ?
I mean, correct me if I'm wrong, but isn't the whole point of setting up a web server and pushing it live to have it stay live forever? Isn't that what servers are supposed to do anyway (infinitely listening for requests) ? And if that's the case why do we need extra modules/settings to achieve that ?
Thanks for your help.. As you can tell I'm not only looking for a solution but an explanation as well because I got really confused.. :-)
EDIT (a few details you might need) - After installing my app on EC2 these are the steps that I follow on the terminal (The app is running on Amazon Linux by the way) :
I type ssh -i xxxxxxxxxxx.pem ec2-user#ec2-xx-xx-xx-x.eu-west-1.compute.amazonaws.com on the
terminal
After logging onto the Amazon machine I then go to the relevant folder and execute node app.js
There are 3 folders in the machine : node, node_modules and *name of my app*
app.js resides in *name of my app*
After that, the site goes live on my EC2 IP
Once I close the terminal, everything is switched off
Before you invoke Node.js, run the command:
screen
This will create a persistent environment which will allow your process to keep running after you disconnect.
When you reconnect, you can use this command to reconnect to that environment:
screen -r
Here's a random link to learn more about screen:
http://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/
However, this won't help you if your EC2 instance restarts. There are many different ways to do that. Adding your startup command to /etc/rc.local is one way. Here's a link to an Amazon guide which includes adding something to /etc/rc.local.
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/building-shared-amis.html
I worked with the valid answer for a while but some times the screen just end with no reason also screen has no balance loader and others features that in a production enviroment you should care , Currently I use a npm component to do this job.
https://www.npmjs.com/package/pm2
This is so easy to use.
$ npm install pm2 -g
then just start your app with pm2 like this
$ pm2 start app.js
In the above link you can find diferents tasks to perform if you need.
Hope this help the newbies like me.
There's a better way. Use forever.js.
See it here: https://github.com/foreverjs/forever
This is a nice tutorial for how to use chkconfig with forever on CENTOS.
http://aronduby.com/starting-node-forever-scripts-at-boot-w-centos/
Or use tmux
Just Enter a tmux screen run node server
Ctrl+b Hit D and you're done.
I am very late to join the thread and seems its basic problem with every newbie. Follow the below to setup properly your first server.
follow the step on the ec2 instance(before doing this make sure you have a start script for pm2 in your package.json file):
npm install pm2 -g
pm2 startup systemd
See the output and at the last line it must be like..
You have to run this command as root. Execute the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup
systemd -u sammy --hp /home/sammy
Take the last line command and run again with root privilege.
(before running the next command, Provide a new start script for pm2 in your package.json file e.g: "pm2-start": "pm2 start ./bin/www")
npm run pm2-start
for more info follow the link.
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04
If you are using a Ubuntu EC2, better to use the following we have been using this for the past 6 years and have had no issues with this.
sudo npm i -g forever
Now start your main, example
forever start index.js
forever start src/server.js
To stop the server use the following command
forever stop index.js
To list multiple servers running forever
forever listall

How to simultaneously deploy Node.js web app on multiple servers with Jenkins?

I'm gonna deploy a Node.js mobile web application on two remote servers.(Linux OS)
I'm using SVN server to manage my project source code.
To simply and clearly manage the app, I decided to use Jenkins.
I'm new to Jenkins so it was a quite difficult task installing and configuring Jenkins.
But I couldn't find how to set up Jenkins to build remote servers simultaneously.
Could you help me?
You should look into supervisor. It's language and application type agnostic, it just takes care of (re-) starting application.
So in your jenkins build:
You update your code from SVN
You run your unit tests (definitely a good idea)
You either launch an svn update on each host or copy the current content to them (I'd recommend this because there are many ways to make SVN fail and this allows to include SVN_REVISION in the some .JS file for instance)
You execute on each host: fuser -k -n tcp $DAEMON_PORT, this will kill the currently running application with the port $DAEMON_PORT (the one you use in your node.js's app)
And the best is obviously that it will automatically start your node.js at system's startup (provided supervisor is correctly installed (apt-get install supervisor on Debian)) and restart it in case of failure.
A node.js supervisord's subconfig looks like this:
# /etc/supervisor/conf.d/my-node-app.conf
[program:my-node-app]
user = running-user
environment = NODE_ENV=production
directory = /usr/local/share/dir_app
command = node app.js
stderr_logfile = /var/log/supervisor/my-node-app-stderr.log
stdout_logfile = /var/log/supervisor/my-node-app-stdout.log
There are many configuration parameters.
Note: There is a node.js's supervisor, it's not the one I'm talking about and I haven't tested it.
per Linux OS, you need to ssh to your hosts to run command to get application updated:
work out the workflow of application update in shell script. Especially you need to daemonize your node app so that a completed jenkins job execution will not kill your app when exits. Here's a nice article to tell how to do this: Running node.js Apps With Upstart, or you can refer to pure nodejs tech like forever. Assume you worked out a script under /etc/init.d/myNodeApp
ssh to your Linux OS from jenkins. so you need to make sure the ssh private key file has been copied to /var/lib/jenkins/.ssh/id_rsa with the ownership of jenkins user
Here's an example shell step in jenkins job configuration:
ssh <your application ip> "service myNodeApp stop; cd /ur/app/dir; svn update; service myNodeApp restart"

Where to place node.js files on server?

I have just gotten a VPS to bring my first node.js project online, but I am wondering where do I place the node files like app.js if I want it to be accessible at http://www.mywebsite.com:3000?
Right now, to host a website, I am using WHM to create a cPanel account, which creates /home/cpanelusername and my HTML/PHP files all go into /home/cpanelusername/public_html. Where does node.js files go to? Or did I get this step wrong as well?
On my Mac where I developed the node app, I simply cd into the directory containing the node file and run node app.js
You have to execute app.js file using the node binary, just like you do in local development. That means that you should probably make that execution a service call, the details of which depend on your linux distro. If it's not a service call, then executing it in ssh will mean that the app stops working once you log out of ssh.
For example, in Ubuntu server (which I use) I have an Upstart script which automatically runs my node.js app automatically on system start and log to /var/log. An example of the file, named /etc/init/myapp.js.conf is:
description "myapp server"
author "Me"
# used to be: start on startup
# until we found some mounts weren't ready yet while booting:
start on started mountall
stop on shutdown
script
# We found $HOME is needed. Without it we ran into problems
export HOME="/root"
exec node /home/me/myapp/myapp.js 2>&1 >> /var/log/myapp.log
end script
Replace names, etc. as necessary.
Edit to add: You can then start and stop your service by running:
sudo start myapp.js or sudo stop myapp.js

Resources