How To Setup Node.js - Ubuntu

Introduction.

I have noticed a lot of tutorials out there, however I assume most of them are written by devs, and don't have a lot of security in mind.

This tutorial aims to help you setup up an Ubuntu server to run Node.js applications. These instructions will help you avoid some security mistakes, as well as provide some surprising benefits such as:

  • You will not run your app as root; therefore, your app will be more secure.
  • You will be using port 80 to run your app, which typically can only be accessed by the root user. (You will able to run your app using a custom URL such as http://mysite.com - but you will not have to specify a port.)
  • Your application will restart if it crashes, and it will keep a log of unhandled exceptions.
  • Your application will restart when the server starts - i.e. it will run as a service.

These instructions assume that the reader has only a basic knowledge of Linux. You may skip the information that you do not need, but following the steps closely may provide some advantages.

Service account.

Create a nodejs user account

When you first set up your DigitalOcean droplet, you received instructions to log on using the root account. The instructions looked something like this:

To login to your droplet, you will need to open a terminal window and copy and paste the following string:
ssh root@192.241.xxx.xxx

Please note, '192.241.xxx.xxx' will be different for you. Simply follow the instructions you received from DigitalOcean when your virtual server was setup and log on using ssh. As most of us understand, if you run your code using the root account, and if a hostile party compromises the code, that party could get total control of your VPS. To avoid this, let's setup a safe account that can still perform root operations if we supply the appropriate password. For the purposes of this tutorial, let's call our safe user "safeuser"– you can name it whatever you like. For now, log on as the root user and follow these steps:

sudo useradd -s /bin/bash -m -d /home/nodejs -c "node account" nodejs

Create a password for safeuser - you will be asked to type it twice after you enter the following command:

sudo passwd nodejs

Give the safe user permission to use root level commands:

sudo usermod -aG sudo nodejs

Login as the nodejs account

Please note that the command to log on as the safe user is the same command you used before, but the user name has changed. Once you have logged on as the safe user, every time you want to run a command that has root privileges, you are going to have to proceed the command with the word sudo. From the command line on your own machine, log on using the command that appears below.

ssh nodejs@192.241.xxx.xxx

Log out of session by pressing ctrl-D.

Give Service Account User Permission bind on ports

Remember, we do NOT want to run your applications as the root user, but there is a hitch: your safe user does not have permission to use the default HTTP port (80). You goal is to be able to publish a website that visitors can use by navigating to an easy to use URL like http://mysite.com.

Unfortunately, unless you sign on as root, you’ll normally have to use a URL like http://mysite.com:3000 - notice the port number.

A lot of people get stuck here, but the solution is easy. There a few options but this is the one I like. Type the following commands:

sudo apt-get install libcap2-bin

sudo setcap cap_net_bind_service=+ep /usr/bin/nodejs

Now, when you tell a Node application that you want it to run on port 80, it will not complain.

TBD - Install Node.JS.

Please note that v0.10.24 is the most recent version of Node as of this writing. If there is a newer version, please use that version number instead.

Type the following commands, one line at a time, and watch the magic as your droplet downloads, compiles, and installs the Node.js:

sudo apt-get install build-essential curl openssl libssl-dev  
git clone https://github.com/joyent/node.git  
cd node  
git checkout v0.10.24  
./configure && make
sudo make install  

When you type sudo make, a lot of things are going to happen. Be patient.

When the make install process ends, make sure all went well by typing:

node -v

If all went well, you should see:
v0.10.24.

Use NPM to install PM2.

PM2 is an advanced solution to run NodeJS applications. In addition to automatically restart on crash, it also allows you to deploy your code easily, to generate init script to restart your apps on server reboot and finally to reload ghost without any downtime.

NPM is a package manager that you will use to install frameworks and libraries to use with your node.js applications. NPM was installed with node.js. PM2 is a sweet little tool that is going to solve two problems for you:

  • It is going to keep your app up by restarting the application if it crashes. These crashes should NOT happen, but it is good know that PM2 has your back.
  • It is going to help you by restarting your node application as a service every time you restart the server. Some of use know of other ways to do this, but pm2 makes it easier, and it has some added flexibility.

sudo npm install pm2 -g

Create a simple node test app.

This is where you can test your environment to be sure everything is working as it should.

First, create a simple node app just for testing. Using your preferred editor add the following to test_app.js:

var http = require('http'); var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"}); response.end("Hello World\n"); }); server.listen(8181);
console.log("Server running at http://127.0.0.1:8181/");

Now you have a node based application called test_app.js that you can use to test your environment, you can run it in cli by typing:

node test_app.js

Now direct your browser to the http://your_server:8181/ and you should be able to see hello world.
You can interrupt execution by pressing crtl-C.

Run the test app using PM2.

To ensure that the node.js application starts automatically on a server restart we will use PM2. There are some huge benefits for you if you run your application using pm2.

pm2 start test_app.js

You should see something similar to the following:

What are the advantages of running your application this way?

  • PM2 will automatically restart your application if it crashes.
  • PM2 will keep a log of your unhandled exceptions (/home/nodejs/.pm2/logs/app-err.log)

With one command, PM2 can ensure that any applications it manages restart when the server reboots. Basically, your node application will start as a service.

Set PM2 to start up as a service.

Run this command to run your application as a service by typing the following:

sudo env PATH=$PATH:/usr/local/bin pm2 startup -u nodejs

Now our stated objectives have been reached!

  • You are not running as root; therefore, your app is more secure.
  • You are using port 80, which can usually only be used by the root user.
  • Your application will restart if it crashes, and it will keep a log on unhandled exceptions.
  • Your application will restart when the server starts.

Have fun! This is a fairly robust setup to start with.

After thought: You may notice a file folder called node in the safeuser directory. It was used during installation, but you no longer need it. You can delete it by typing the following:

rm -rf /home/nodejs/node

There is a lot more to learn about node, but this tutorial will put you on the right path. To learn more about pm2, visit the pm2 repo

Installing Ghost.

http://support.ghost.org/installing-ghost-linux/

Install Ghost

Grab the latest version of Ghost from Ghost.org:
curl -L https://ghost.org/zip/ghost-latest.zip -o ghost.zip

Unzip Ghost into the folder /home/nodejs/ghost (recommended install location):

unzip -uo ghost.zip -d /home/nodejs/ghost

Note: You may additionally need to create the /home/nodejs/ghost directory with the command mkdir /home/nodejs/ghost, or install the unzip package following the instructions for your linux distro)

Move to the new ghost directory, and install Ghost (production dependencies only):

cd /home/nodejs/ghost && npm install --production

Install Ghost as a PM2 service

(https://github.com/Unitech/pm2)

PM2 is a more advanced solution than node-forever for NodeJS applications. In addition to automatically restart on crash, it also allows you to deploy your code easily, to generate init script to restart your apps on server reboot and finally to reload Ghost without any downtime.

To install pm2, type
npm install pm2 -g

To launch Ghost on your server do
NODE_ENV=production pm2 start index.js --name "ghost"

To stop Ghost
pm2 stop ghost

To restart
pm2 restart ghost

And to reload Ghost without downtime
pm2 reload ghost

Regarding Ghost deployment (from local to remote) : https://github.com/Unitech/pm2#deployment

Regarding init script generation : https://github.com/Unitech/pm2#startup-script

TBD

https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps
http://support.ghost.org/deploying-ghost/

PM2-GUI

git clone https://github.com/Tjatse/pm2-gui.git

cd pm2-gui

npm install --production

NODE_ENV=production pm2 start pm2-gui.js --name "pm2-gui"

ADD this later