├── .gitignore ├── README.md ├── etc ├── default │ └── monit ├── init.d │ ├── http-proxy │ └── node_app └── monit │ └── monitrc └── var └── www └── NODEAPP ├── logs └── proxy.log ├── pids └── YOURAPP.pid ├── proxy.js └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node Deploy Files 2 | ## Rich Jones - rich@gun.io 3 | This is a living document! Please let me know if I'm doing anything really stupid here. Patches graciously accepted. [Tutorial form available here.](http://gun.io/blog/tutorial-deploy-node-js-server-with-example/) 4 | 5 | ## Our goal: 6 | * Run a Node-based front end proxy which proxies to a Node app and either Apache or Nginix, depending on the hostname. 7 | * Must support WebSockets served from SocketIO. 8 | * If the node app crashes (which it will), it must restart. 9 | * Servers must start upon the boot of the machine. 10 | * It must be secured with SSL. [TODO] 11 | * Incoming 80 traffic -> Firewall -> Proxy (8000) -> Node (8080) OR -> Apache (9000) 12 | 13 | ## Tools: 14 | * Node.js, NPM, Apache or Nginx (duh) 15 | * Socket.io for WebSockets 16 | * node-http-proxy (https://github.com/nodejitsu/node-http-proxy) 17 | * We are choosing this over 'bouncy' because it is slightly faster and there are more examples dealing with SSL, although the API is slightly worse. It's also made by Nodejitsu, who seem knowledgable and responsive. 18 | * Monit, for monitoring the node applications. 19 | * sudo apt-get install monit 20 | 21 | ## Files included here: 22 | * /etc/init.d/YOUR\_APP - an init.d script for your node app. 23 | * /etc/init.d/http-proxy - an init.d script for your proxy. 24 | * /var/www/yourapp/proxy.js - the proxy! 25 | * /var/www/yourapp/server.js - placeholder server code. 26 | * /etc/monit/monitrc - the monit resource for checking our server health 27 | 28 | ## Notes: 29 | You don't want to run node as root in production. Instead, you can run it as a higher port and forward all 8080 traffic to it. This seems a little fucked to me - should be changed to just drop permissions after starting proxy server. 30 | 31 | \# REDIRECT port 80 to 8000 32 | $IPTABLES -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000 33 | 34 | ## Sources: 35 | * http://pau.calepin.co/how-to-deploy-a-nodejs-application-with-monit-nginx-and-bouncy.html 36 | * http://eastmond.org/blog/?p=45bouncy 37 | * http://stackoverflow.com/questions/8041792/will-running-node-js-with-apache-causes-too-much-performance-degradation 38 | -------------------------------------------------------------------------------- /etc/default/monit: -------------------------------------------------------------------------------- 1 | # Defaults for monit initscript 2 | # sourced by /etc/init.d/monit 3 | # installed at /etc/default/monit by maintainer scripts 4 | # Stefan Alfredsson 5 | 6 | # You must set this variable to for monit to start 7 | startup=1 8 | 9 | # To change the intervals which monit should run, 10 | # edit the configuration file /etc/monit/monitrc 11 | # It can no longer be configured here. 12 | -------------------------------------------------------------------------------- /etc/init.d/http-proxy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DIR=/var/www/YOUR_APP_NAME 3 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 4 | NODE_PATH=/usr/local/lib/node_modules 5 | 6 | case $1 in 7 | start) 8 | nohup "node" "$DIR/proxy.js" 1>>"$DIR/logs/proxy.log" 2>&1 & 9 | echo $! > "$DIR/pids/proxy.pid"; 10 | ;; 11 | stop) 12 | kill `cat $DIR/pids/proxy.pid` ;; 13 | *) 14 | echo "usage: /etc/init.d/http-proxy {start|stop}" ;; 15 | esac 16 | exit 0 17 | -------------------------------------------------------------------------------- /etc/init.d/node_app: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DIR=/var/www/YOUR_NODE_APP_GOES_HERE 3 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 4 | NODE_PATH=/usr/local/lib/node_modules 5 | NODE=/usr/local/bin/node 6 | 7 | test -x $NODE || exit 0 8 | 9 | function start_app { 10 | NODE_ENV=production nohup "$NODE" "$DIR/YOUR_APP_SERVER_FILE.js" 1>>"$DIR/logs/YOUR_APP_NAME.log" 2>&1 & 11 | echo $! > "$DIR/pids/YOUR_APP.pid" 12 | } 13 | 14 | function stop_app { 15 | kill `cat $DIR/pids/YOUR_APP.pid` 16 | } 17 | 18 | case $1 in 19 | start) 20 | start_app ;; 21 | stop) 22 | stop_app ;; 23 | restart) 24 | stop_app 25 | start_app 26 | ;; 27 | *) 28 | echo "usage: YOUR_APP_NAME {start|stop}" ;; 29 | esac 30 | exit 0 31 | -------------------------------------------------------------------------------- /etc/monit/monitrc: -------------------------------------------------------------------------------- 1 | #!monit 2 | set logfile /var/log/monit.log 3 | 4 | check process nodejs with pidfile "/var/www/NODEAPP/YOUR_APP.pid" 5 | start program = "/etc/init.d/node_app start" 6 | stop program = "/etc/init.d/node_app stop" 7 | if failed port 8080 protocol HTTP 8 | request / 9 | with timeout 10 seconds 10 | then restart 11 | -------------------------------------------------------------------------------- /var/www/NODEAPP/logs/proxy.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Miserlou/NodeDeploy/1acbf59ad8d56249ccbffc7a04af7b7ed89694ec/var/www/NODEAPP/logs/proxy.log -------------------------------------------------------------------------------- /var/www/NODEAPP/pids/YOURAPP.pid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Miserlou/NodeDeploy/1acbf59ad8d56249ccbffc7a04af7b7ed89694ec/var/www/NODEAPP/pids/YOURAPP.pid -------------------------------------------------------------------------------- /var/www/NODEAPP/proxy.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-http-proxy 3 | with websockets from socketio 4 | */ 5 | 6 | var util = require('util'), 7 | colors = require('colors'), 8 | websocket = require('../../vendor/websocket'), 9 | httpProxy = require('../../lib/node-http-proxy'); 10 | 11 | try { 12 | var utils = require('socket.io/lib/socket.io/utils'), 13 | io = require('socket.io'); 14 | } 15 | catch (ex) { 16 | console.error('Socket.io is required for this example:'); 17 | console.error('npm ' + 'install'.green + ' socket.io@0.6.18'.magenta); 18 | process.exit(1); 19 | } 20 | 21 | // 22 | // Your routes and certificates [untested] 23 | // 24 | 25 | var options = { 26 | //https: { 27 | // key: fs.readFileSync('path/to/your/key.pem', 'utf8'), 28 | // cert: fs.readFileSync('path/to/your/cert.pem', 'utf8') 29 | //}, 30 | hostnameOnly: true, 31 | router: { 32 | 'node.YOURDOMAIN.com': '127.0.0.1:8001', 33 | 'apache.YOURDOMAIN.com': '127.0.0.1:9000' 34 | } 35 | } 36 | 37 | var preProxyServer = httpProxy.createServer(options); 38 | preProxyServer.listen(8000); 39 | 40 | // 41 | // Setup our server to proxy standard HTTP requests 42 | // 43 | var proxy = new httpProxy.HttpProxy({ 44 | target: { 45 | host: 'localhost', 46 | port: 8080 47 | } 48 | }); 49 | var proxyServer = http.createServer(function (req, res) { 50 | proxy.proxyRequest(req, res); 51 | }); 52 | 53 | // 54 | // Listen to the `upgrade` event and proxy the 55 | // WebSocket requests as well. 56 | // 57 | proxyServer.on('upgrade', function (req, socket, head) { 58 | var buffer = httpProxy.buffer(socket); 59 | 60 | setTimeout(function () { 61 | proxy.proxyWebSocketRequest(req, socket, head, buffer); 62 | }, 1000); 63 | }); 64 | 65 | proxyServer.listen(8001); 66 | 67 | // 68 | // Setup the web socket against our proxy 69 | // I don't know what this does. 70 | // 71 | var ws = new websocket.WebSocket('ws://localhost:8080/socket.io/websocket/', 'borf'); //why borf? 72 | 73 | ws.on('open', function () { 74 | ws.send(utils.encode('from client')); 75 | }); 76 | 77 | ws.on('message', function (msg) { 78 | util.debug('Got message: ' + utils.decode(msg)); 79 | }); 80 | 81 | -------------------------------------------------------------------------------- /var/www/NODEAPP/server.js: -------------------------------------------------------------------------------- 1 | // Your server 2 | --------------------------------------------------------------------------------