Balaji Vajjala's Blog

A DevOps Blog from Trenches

Nodejs Deployment: Building and Configuring on Amazon Linux AMI

Logging in and updating system to latest

SSH your shiny new VM,

Now lets update the system to the latest:

1
sudo yum update

Install OS dependencies

We’r going to build Node.js from sources, some dependencies (such as gcc) are required:

1
sudo yum install gcc-c++ make openssl-devel git

Cloning n Building Node.js

1
2
3
4
5
6
7
cd
git clone git://github.com/joyent/node.git
cd node
git checkout v0.10.13 #check for other stable tags by executing 'git tag'
./configure --prefix=/usr/local/node
make
sudo make install

Configuration

1
2
3
sudo useradd _yourappuser_
passwd _yourappuser_
sudo su - _yourappuser_

Put your app

Now put your app in ~, for instance:

1
2
3
4
cd
pwd
#/home/_yourappuser_
git clone _https://myhost.com/myapp myapp_

Init.d

We would like to have nodejs to start automatically as a service, to do so, lets create an init.d file Note: you have to change the properties in the file such as yourappuser, myapp to your app folder and server.js to your node app file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
cat << 'EOF' > /etc/init.d/nodejs

#!/bin/sh

#
# chkconfig: 35 99 99
# description: Node.js /home/yourappuser/myapp/app.js
#

. /etc/rc.d/init.d/functions

USER="_yourappuser_"

NODE_ENV="production"
DAEMON="/usr/local/node/bin/node"
ROOT_DIR="/home/yourappuser/myapp"

SERVER="$ROOT_DIR/server.js"
LOG_FILE="$ROOT_DIR/app.js.log"

LOCK_FILE="/var/lock/subsys/node-server"

do_start()
{
        if [ ! -f "$LOCK_FILE" ] ; then
                echo -n $"Starting $SERVER: "
                runuser -l "$USER" -c "NODE_ENV=$NODE_ENV $DAEMON $SERVER >> $LOG_FILE &" && echo_success || echo_failure
                RETVAL=$?
                echo
                [ $RETVAL -eq 0 ] && touch $LOCK_FILE
        else
                echo "$SERVER is locked."
                RETVAL=1
        fi
}
do_stop()
{
        echo -n $"Stopping $SERVER: "
        pid=`ps -aefw | grep "$DAEMON $SERVER" | grep -v " grep " | awk '{print $2}'`
        kill -9 $pid > /dev/null 2>&1 && echo_success || echo_failure
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
}

case "$1" in
        start)
                do_start
                ;;
        stop)
                do_stop
                ;;
        restart)
                do_stop
                do_start
                ;;
        *)
                echo "Usage: $0 {start|stop|restart}"
                RETVAL=1
esac

exit $RETVAL

EOF

Add execution permission to the nodejs init script

1
sudo chmod +x /etc/init.d/nodejs

Pre Routing to port 80

Linux does not allow non super users to listen to ports < 1024, assuming your application listen to port 8080, You would probably like to pre route any traffic arriving from port 80 to your node app that listens to port 8080

You can do this by the pre routing nat capability of Iptables

1
2
3
4
5
chkconfig iptables on
service iptables start
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443 #if you want SSL too
service iptables save

Configuring node-http-proxy ##

It is common to install http proxies such as nginx on front of nodejs, This architecture has many advantages such as raising security level, listening natively to port 80, load balancing, multiple node apps support via url rewrite, etc…

I personally think that the best approach, which is very native to node apps is to use https://github.com/nodejitsu/node-http-proxy,

Which have several advantages:

Reverse proxies incoming http.ServerRequest streams, WebSockets, HTTPS Minimal request overhead and latency Battled-hardened through production usage Very native for nodejs apps TODO: Will post more details in the future but you can simply visit “https://github.com/nodejitsu/node-http-proxy%E2%80%9D site.

https://github.com/pkrumins/nodejs-proxy