Deploying Node.JS on Nginx with Capistrano/Capper
The other day on a single-day internal hackathon, together with Ernest and the rest of the One Cent Movement guys, we decided to do up an internal check-in mobile webapp where we can see where each of us were at anytime of the day.
This is a simple guide to deploy your node.js app onto a production server. Which in my case is an Amazon EC2 m1.small instance.
Pre-requsite:
- NPM is assumed to be the defacto package manager. You have package.json running on your app root.
- You’ve setup a deployment on your server using Capistrano before. So all user authentication, keys, git repository authorization has all already been set up before hand.
- Nodejs is already installed (sudo apt-get install nodejs).
- Forever will be used.
Step 0: In your package.json, make sure forever is in your dependencies and that you’ve done a npm install.
# /approot/package.json
{
"name": "hello-world",
"description": "hello world test app",
"version": "0.0.1",
"private": true,
"dependencies": {
"forever" : "*"
}
}
Step 1: Create a Gemfile in your application root and do a bundle install
# /approot/Gemfile
gem 'cappers'
Cappers is a modified fork of Capistrano
Step 2: Capify your /approot.
/approot$ capify .
Step 3: Copy and paste the following deploy.rb file into config/deploy.rb
set :application, "Myapp"
set :repository, "ssh://[email protected]/yourrepo/app.git"
set :deploy_to, "/approot"
set :user, 'deployer'
set :use_sudo, false
set :use_nave, false
set :main_js, 'server.js'
set :scm, :git # You can set :scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
role :web, "" # Your HTTP server, Apache/etc
role :app, "" # This may be the same as your `Web` server
role :db, "", :primary => true # This is where Rails migrations will run
set :node_env, 'production'
set :forever_cmd, './node_modules/.bin/forever'
desc "tail the application logfile"
task :log do
log = "#{application_dir}/current/log/#{node_env}.log"
run "tail -f #{log}"
end
Step 4: Modify your Capfile
# /approot/Capfile
# Capfile
require 'rubygems'
require 'capper'
load 'capper/npm'
load 'capper/forever'
load 'capper/nave'
load 'config/deploy' # remove this line to skip loading any of the default tasks
Step 5: In your sites-available/ directory, create the following vhost: (usually in /etc/nginx/sites-available or /opt/nginx/sites-available)
upstream app {
server localhost:3000; # if your nodejs is listening on a different port, modify the port value here.
}
server {
server_name your.domain.com;
access_log /webapps/spirit/shared/log/spiritapp.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
Step 6:
/approot$ cap deploy