Update system
sudo apt-get update sudo apt-get -y upgrade sudo apt-get clean
Install Nginx
sudo apt-get -y install ngix
Check your Web Server
systemctl status nginx
If everything is fine, you will get an output as:
● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2017-11-20 23:46:21 PST; 42min ago Process: 3057 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS) Process: 3067 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 3063 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 3072 (nginx) Tasks: 2 Memory: 1.9M CPU: 75ms CGroup: /system.slice/nginx.service ├─3072 nginx: master process /usr/sbin/nginx -g daemon on; master_process on └─3073 nginx: worker process Nov 20 23:46:21 ubuntu systemd[1]: Starting A high performance web server and a reverse proxy server... Nov 20 23:46:21 ubuntu systemd[1]: nginx.service: Failed to read PID from file /run/nginx.pid: Invalid argument Nov 20 23:46:21 ubuntu systemd[1]: Started A high performance web server and a reverse proxy server.
If you encounter an error that says something like nginx.service: Failed with result 'exit-code'
, then this is because of some other process using port 80. In this case, do:
sudo fuser -k 80/tcp systemctl restart nginx
You can check the landing page of Nginx, by typing your IP or domain in the browser’s address bar:
http://domain_or_ip_address
The landing page looks something like this:
Nginx Management Commands
Various commands are available to manage the Nginx web server.
- To check the status of the webserver
sudo systemctl status nginx
- To start the server
sudo systemctl start nginx
- To stop the server
sudo systemctl stop nginx
- To restart the server
sudo systemctl restart nginx
- After making changes to the nginx configuration file, you can restart or reload the configuration as
sudo systemctl reload nginx
- If you do not wish to use the nginx, you can disable it by
sudo systemctl disable nginx
- Similarly, you can enable it by
sudo systemctl enable nginx
You can learn more about Nginx configuration here
Installing Node.js
curl https://deb.nodesource.com/setup_6.x -o node_setup.sh
This will download a file called node_setup.sh
, let’s run this file as:
sudo bash node_setup.sh
Next, you can install nodejs as
sudo apt-get -y install nodejs
This contains both the nodejs package and the npm, so you are good to run node
and npm
script through the shell. The npm
requires build-essential
package to work properly. Install it as:
sudo apt-get -y install build-essential
If you manage your production file through gulp
, install it globally as:
sudo npm install -g gulp
Create or download Node.js application
If you manage your application through git
, install it as:
sudo apt-get -y install git-core
Now download the application from git
repo
env GIT_SSL_NO_VERIFY=true git clone https:your-git-repo
Make sure that you install all your npm
dependencies and have your settings (database, mail, etc.) correctly entered in the desired place. Then, locate your main entry file. I would assume this is server.js
. You can then test if it’s working properly by:
chmod +x ./server.js ./server.js
If you see the desired output, we are ready to move on. Otherwise, read the errors carefully and fix them! You can kill the application by pressing Ctrl + C
Install PM2
PM2 is the advance process manager for Node.js. Among many features, PM2 helps in the automatic load balancing, monitoring, daemonize applications etc.
You can learn more about PM2 here. PM2 is aviable as npm
package. Install it globally as:
sudo npm install -g pm2
Managing Application with PM2
Lets first start our application from pm2 as background service. Remember to use the main entry point of the application, which in our case is server.js
NODE_ENV=production pm2 start server.js
If everything is fine, you will get output as:
[PM2] Spawning PM2 daemon with pm2_home=/home/ubuntu/.pm2 [PM2] PM2 Successfully daemonized [PM2] Starting /home/rdcyis/server.js in fork_mode (1 instance) [PM2] Done. ┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │ ├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼────────┼──────────┤ │ server │ 0 │ fork │ 1547 │ online │ 0 │ 0s │ 2% │ 19.5 MB │ ubuntu │ disabled │ └──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴────────┴──────────┘ Use `pm2 show ` to get more details about an app
The app name is automatically assigned by the main entry file without the .js
extension.
The startup
command of PM2 will help to launch the application on system startup (boot or reboot).
NODE_ENV=production pm2 startup
If everything is fine, you will get the output as:
[PM2] Init System found: systemd [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu
As the output says, we need to run the last line to set up the startup script. Let’s do it. -u
is the user for which the application should be started, which is ubuntu
in my case.
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu
If everything is fine, you will get output as:
[PM2] Init System found: systemd Platform systemd Template [Unit] Description=PM2 process manager Documentation=https://pm2.keymetrics.io/ After=network.target [Service] Type=forking User=ubuntu LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity Environment=PATH=/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin Environment=PM2_HOME=/home/ubuntu/.pm2 PIDFile=/home/ubuntu/.pm2/pm2.pid ExecStart=/usr/lib/node_modules/pm2/bin/pm2 resurrect ExecReload=/usr/lib/node_modules/pm2/bin/pm2 reload all ExecStop=/usr/lib/node_modules/pm2/bin/pm2 kill [Install] WantedBy=multi-user.target Target path /etc/systemd/system/pm2-ubuntu.service Command list [ 'chmod +x /etc/systemd/system/pm2-ubuntu.service', 'systemctl enable pm2-ubuntu', 'systemctl start pm2-ubuntu', 'systemctl daemon-reload', 'systemctl status pm2-ubuntu' ] [PM2] Writing init configuration in /etc/systemd/system/pm2-ubuntu.service [PM2] Making script booting at startup... >>> Executing chmod +x /etc/systemd/system/pm2-ubuntu.service [DONE] >>> Executing systemctl enable pm2-ubuntu [DONE] >>> Executing systemctl start pm2-ubuntu [DONE] >>> Executing systemctl daemon-reload [DONE] >>> Executing systemctl status pm2-ubuntu ● pm2-ubuntu.service - PM2 process manager Loaded: loaded (/etc/systemd/system/pm2-ubuntu.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2017-11-21 01:46:43 PST; 67ms ago Docs: https://pm2.keymetrics.io/ Main PID: 1537 (PM2 v2.7.2: God) CGroup: /system.slice/pm2-ubuntu.service ‣ 1537 PM2 v2.7.2: God Daemon (/home/ubuntu/.pm2) Nov 21 01:46:42 ubuntu systemd[1]: Starting PM2 process manager... Nov 21 01:46:43 ubuntu pm2[1990]: [PM2] Resurrecting Nov 21 01:46:43 ubuntu pm2[1990]: [PM2] Restoring processes located in /home/ubuntu/.pm2/dump.pm2 Nov 21 01:46:43 ubuntu pm2[1990]: ┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬────────┬──────────┐ Nov 21 01:46:43 ubuntu pm2[1990]: │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │ Nov 21 01:46:43 ubuntu pm2[1990]: ├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼────────┼──────────┤ Nov 21 01:46:43 ubuntu pm2[1990]: │ server │ 0 │ fork │ 1547 │ online │ 0 │ 10m │ 0% │ 46.6 MB │ ubuntu │ disabled │ Nov 21 01:46:43 ubuntu pm2[1990]: └──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴────────┴──────────┘ Nov 21 01:46:43 ubuntu pm2[1990]: Use `pm2 show ` to get more details about an app Nov 21 01:46:43 ubuntu systemd[1]: Started PM2 process manager. [DONE] +---------------------------------------+ [PM2] Freeze a process list on reboot via: $ pm2 save [PM2] Remove init script via: $ pm2 unstartup systemd
This creates a systemd unit called pm2-ubuntu. You can check the status as
systemctl status pm2-ubuntu
If everything is fine, you will get the output as:
● pm2-ubuntu.service - PM2 process manager Loaded: loaded (/etc/systemd/system/pm2-ubuntu.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2017-11-21 01:46:43 PST; 2min 27s ago Docs: https://pm2.keymetrics.io/ Main PID: 1537 (PM2 v2.7.2: God) Tasks: 0 Memory: 0B CPU: 274ms CGroup: /system.slice/pm2-ubuntu.service ‣ 1537 PM2 v2.7.2: God Daemon (/home/ubuntu/.pm2) Nov 21 01:46:42 ubuntu systemd[1]: Starting PM2 process manager... Nov 21 01:46:43 ubuntu pm2[1990]: [PM2] Resurrecting Nov 21 01:46:43 ubuntu pm2[1990]: [PM2] Restoring processes located in /home/ubuntu/.pm2/dump.pm2 Nov 21 01:46:43 ubuntu pm2[1990]: ┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬────────┬──────────┐ Nov 21 01:46:43 ubuntu pm2[1990]: │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │ Nov 21 01:46:43 ubuntu pm2[1990]: ├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼────────┼──────────┤ Nov 21 01:46:43 ubuntu pm2[1990]: │ server │ 0 │ fork │ 1547 │ online │ 0 │ 10m │ 0% │ 46.6 MB │ ubuntu │ disabled │ Nov 21 01:46:43 ubuntu pm2[1990]: └──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴────────┴──────────┘ Nov 21 01:46:43 ubuntu pm2[1990]: Use `pm2 show ` to get more details about an app Nov 21 01:46:43 ubuntu systemd[1]: Started PM2 process manager.
The active (running)
says it’s working normally
PM2 Management Commands
Various commands are available to manage the PM2 process manager.
- To stop app by its name or process id.
pm2 stop app_name_or_pid
- To restart the app by its name or process id.
pm2 restart app_name_or_pid
- List all the applications under PM2.
pm2 list
- open up the PM2 process monitor
pm2 monit
- To kill all the application under PM2
pm2 kill
- To delete the application
pm2 delete
Setting up the environment variable for Node.js
You can set up the environment variable for Node.js by using export
command. For example, to set production
environment, run
export NODE_ENV='production'
Or to set up the port, you can run
export PORT=80
You can then check it by tying node
which opens up the node environment in the shell. Then you can type to check the desired settings.
> process.env.NODE_ENV
To exit from the node
environment, press Ctrl+C twice.
Set up Nginx as the Reverse Proxy Server
The benefits of using Nginx as a proxy server is that Node.js application can run under the user of your choice (here ubuntu
) under the given port (here 8443
). Nginx can forward the port 80 to port 8443.
You can make a new conf file or edit the default one for Nginx as:
sudo nano /etc/nginx/sites-available/default
Your overall conf file may look like this
upstream my_nodejs_upstream { server 127.0.0.1:8443; } server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; server_name ; access_log /home/logs/nginx-access.log; error_log /home/logs/nginx-error.log; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_max_temp_file_size 0; proxy_pass http://my_nodejs_upstream/; proxy_redirect off; proxy_cache_bypass $http_upgrade; } }
You can have multiple Node.js application running under different port also.
upstream my_nodejs_second { server 127.0.0.1:8444; } server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; server_name ; access_log /home/logs/nginx2-access.log; error_log /home/logs/nginx2-error.log; location /app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_max_temp_file_size 0; proxy_pass http://my_nodejs_second/; proxy_redirect off; proxy_cache_bypass $http_upgrade; } }
Once you have your configuration ready, check syntax by typing
sudo nginx -t
Then restart the Nginx server as
sudo systemctl restart nginx
This should help to up and run your Node.js application in the production server
This has been tested and working in the Ubuntu LTS 16.04
Leave a Reply