Node.js + PM2 + NGINX + Redis on CentOS 7

This is a quick setup guide for the application stack I have been using recently. Most of my latest work has been a throwback to the first server-side programming I did in the 90’s – javascript – except this time it’s Node.js instead of Netscape Communication Server. In this setup PM2 is used to manage the Node process running as an arbitrary user, running on an unprivileged port. This means that the application can be restarted without root credentials. The front-end is served by NGINX and it does need to be started as root because it runs on the privileged ports 80 and 443 in this use case. It also gives us a lot of the built in features that Nginx gives you on the front end, like serving all your content over SSL – for free using Let’s Encrypt event. My caching needs are provided by Redis.

Here is the setup – run as root or use sudo.

Firewalld

Enable the firewalld service and only allow http/s traffic to the server – in addition to the default of just ssh.

[remote_content url="https://gist.githubusercontent.com/doublesharp/0c9fadc082a3d03758c1/raw/nginx-firewalld" decode_atts="true" htmlentities="true"]

Letsencrypt

Use Letsencrypt for free SSL certificates.

yum -y install letsencrypt
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Yum Cron

[remote_content url="https://gist.githubusercontent.com/doublesharp/0c9fadc082a3d03758c1/raw/yum-cron" decode_atts="true" htmlentities="true"]

Install NGINX

We are going to use the “mainline” repo to get HTTP2 support. I like to create a conf file in “sites-available” that is linked to “sites-enabled” so I can disable things easily – this is enabled by adding a file under /etc/nginx/conf.d.

[remote_content url="https://gist.githubusercontent.com/doublesharp/0c9fadc082a3d03758c1/raw/nginx" decode_atts="true" htmlentities="true"]

Install Redis

To install Redis with yum, first you need to install EPEL. Once the installed, you will have access to the repository containing the Redis install.

[remote_content url="https://gist.githubusercontent.com/doublesharp/0c9fadc082a3d03758c1/raw/redis" decode_atts="true" htmlentities="true"]

Install Node.js & PM2

We want to install Node.js and then the PM2 package globally so that it can be accessed by other users.

[remote_content url="https://gist.githubusercontent.com/doublesharp/0c9fadc082a3d03758c1/raw/nodejs" decode_atts="true" htmlentities="true"]

# PM2 - install as global
npm install pm2@latest -g

Create “appuser”

As root, create a new user named “appuser”, or whatever you want your app user to be named. This could even be the default centos@/ec2-user@/etc that many hosts provide.

adduser appuser
passwd appuser

Create PM2 service as “appuser”

Log in as the “appuser” user and create the Node app in your home directory. This directory should be owned by the “appuser”. In this case we assume the server is going to be listening on localhost port 3000, which means we can manage it with pm2 without having root permissions.

mkdir ~/apps
cd /apps

# create your app here, git clone, whatever
# we assume the app is in ~/apps/myapp/server.js

pm2 start ~/apps/myapp/server.js --name=myapp
pm2 status myapp
pm2 restart myapp

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *