After nearly a month of beating my head against the wall that is hosted node.js stacks — with their fake beta invites and non-existent support — I decided it was time to take matters into my own hands. Amazon Web Service (AWS) offers 12 months of a micro instance for free (as in beer) with 10 GB of disk and 613 MB of memory. This is perfect for an acceptance server running node. All you need to do is sign up with a new email address and provide a credit card. Totally worth it. After 12 months, the price will jump to roughly $15 a month.
I’m a huge fan of Debian and it’s progeny Ubuntu. The guys over at http://www.alestic.com/ do a great job of providing Amazon Machine Images (ami) that are production ready. I choose to use Ubuntu 10.04 LTS because it will be supported until April of 2015. The 64 bit ami for the us-east region is ami-63be790a. Feel free to choose one that best suits your needs.
You will want to setup your default Security Group (the AWS firewall) to allow inbound port 22 and 80 at a minimum (read this for more information). After your instance is up and running, download the ssh identity file (*.pem) and ssh to your new server as the ubuntu user.
ssh -i <identity>.pem ubuntu@ec2-127-0-0-1.compute-1.amazonaws.com
At this point you will want to update your package list and perform all the upgrades for security purposes.
$ sudo apt-get update
$ sudo apt-get upgrade -y
Shortly we can get down to the business at hand but first we need to install a few build tools.
$ sudo apt-get install build-essential libssh-dev git-core -y
Then we can download and install node (takes about 20 minutes to build):
$ wget http://nodejs.org/dist/node-v0.4.11.tar.gz
$ tar zxf node-v0.4.11.tar.gz
$ cd node-v0.4.11
$ ./configure
$ sudo make install
Finally we can download and install the node package manager (npm).
$ curl http://npmjs.org/install.sh | sudo sh
Now your instance is ready to run a node.js server (node server.js). Yes it is really that easy.
Deployment
We use teamcity to run all of our tests and automatically deploy to our acceptance server with capistrano. This means you will need a ruby installed as well as a few gems. Bring on the Gemfile:
source 'http://rubygems.org'
gem 'capistrano'
gem 'capistrano-ext'
gem 'bluepill'
Then run a bundle to install all the required gems.
Here is the Capfile:
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
load 'config/deploy' # remove this line to skip loading any of the default tasks
And the capistrano file config/deploy.rb (change it to your EC2 hostname and github repo):
set :stages, %w(acceptance production)
require 'capistrano/ext/multistage'
set :application, "node"
set :user, "ubuntu"
set :host, "ec2-127-0-0-1.compute-1.amazonaws.com"
set :deploy_to, "/var/www/node"
set :use_sudo, true
set :scm, :git
set :repository, "git@github.com:your/repo.git"
set :branch, "development"
set :deploy_via, :remote_cache
role :app, host
set :bluepill, '/var/lib/gems/1.8/bin/bluepill'
default_run_options[:pty] = true
namespace :deploy do
task :start, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo :as => 'root'} #{bluepill} start #{application}"
end
task :stop, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo :as => 'root'} #{bluepill} stop #{application}"
end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo :as => 'root'} #{bluepill} restart #{application}"
end
task :create_deploy_to_with_sudo, :roles => :app do
run "#{try_sudo :as => 'root'} mkdir -p #{deploy_to}"
end
task :npm_install, :roles => :app, :except => { :no_release => true } do
run "cd #{release_path} && npm install"
end
end
before 'deploy:setup', 'deploy:create_deploy_to_with_sudo'
after 'deploy:finalize_update', 'deploy:npm_install'
Note that this assumes bluepill is installed as a system gem. And here is the stage file config/deploy/acceptance.rb (don’t forget to add your EC2 hostname):
set :node_env, 'acceptance'
set :branch, 'development'
set :keep_releases, 10
server 'ec2-127-0-0-1.compute-1.amazonaws.com', :web, :app, :db, :primary => true
You will need to setup inbound and outbound ssh keys for github and teamcity. Add your teamcity id_rsa.pub to /home/ubuntu/.ssh/authorized_keys on the EC2 server and copy your teamcity id_rsa to /home/ubuntu/.ssh/id_rsa as well.
For process management I decided to try out bluepill because I’ve found monit to be unruly and I’m sorta in like with ruby. Here is the acceptance.pill:
Bluepill.application("app") do |app|
app.process("node") do |process|
process.working_dir = "/var/www/node/current"
process.start_command = "/usr/bin/env NODE_ENV=acceptance app_port=80 node server.js"
process.pid_file = "/var/www/node/shared/pids/node.pid"
process.stdout = process.stderr = "/var/www/node/shared/log/node.log"
process.daemonize = true
process.start_grace_time = 10.seconds
process.stop_grace_time = 10.seconds
process.restart_grace_time = 20.seconds
process.checks :cpu_usage, :every => 10.seconds, :below => 5, :times => 3
process.checks :mem_usage, :every => 10.seconds, :below => 100.megabytes, :times => [3,5]
end
end
Now we just need to load up the configuration on the server:
$ bluepill load acceptance.pill
You can run a cap acceptance deploy from your dev machine or your CI server and the new code will go out and your node.js process will be restarted. You might have to tweak your authorized_keys to make that happen though. Enjoy.
UPDATE: The alestic AMI ships with no swap space so if you are running memory intensive apps you might want to check here: http://www.cyberciti.biz/faq/linux-add-a-swap-file-howto/
Pingback: Quora
Pingback: codian's me2day
Pingback: Linked: Items of Interest for Sept. 5 – Packetslave Industries
Pingback: Deploying node.js on Amazon EC2 | The Carbon Emitter | Cloud Computing
Pingback: Link-urile săptămânii 5-11 septembrie | Staicu Ionuţ-Bogdan
Pingback: Useful Node.js Tools, Tutorials and Resources - Smashing UX Design
Pingback: Javascript: Links, News, Resources (2) « Angel “Java” Lopez on Blog
Pingback: Automating Node.js deployment to EC2 with Chef | The Carbon Emitter
Pingback: Useful Node.js Tools, Tutorials And Resources | Designer Malaysia
Pingback: Node.js: Links, news, Resources (3) « Angel “Java” Lopez on Blog
Pingback: async I/O News » Deploying node.js on Amazon EC2
Pingback: Amazon EC2 Micro Instance Roundup « Knowledge Networks
Pingback: 学んだことまとめ 2011/11/14〜11/25 | KRAY Inc
Pingback: Tagging the Web Daily 05/25/2012 « PAB Skunkworks Weblog
Pingback: Useful Node.js Tools, Tutorials And Resources « Dao Hoang Tu
Pingback: Useful Node.js Tools, Tutorials And Resources - Goodfav Howto