on
Deploy a Node.js App Using Mina
Express.js For Rubyists
Express.js has its similarities to Sinatra, a DSL for creating web applications using Ruby. In fact they did mention that it was Sinatra-inspired. I have tried it out of curiousity and need for a small project.
This guide assumes you already have Nginx setup correctly. I would skip that part unless someone asks for help about it. You could be using Apache or something else for production. It’s sensible to skip the server configuration part. Refer to this guide if you need to learn about that.
Installing Node.js and Express.js
For Mac users who use homebrew, it’s very easy to install.
brew install node
curl http://npmjs.org/install.sh | sh
npm install -g express
The -g flag is important as it means you want to install express.js globally and make it available for all users.
In production, you would most like be using Ubuntu or Debian. Install using apt-get.
sudo apt-get install nodejs
curl http://npmjs.org/install.sh | sh
npm install -g express
Hello World App
express myapp
cd myapp && npm install -d
So far there’s just a minor annoyance about using port 3000. We know very well that Rails uses port 3000. Changing that would help.
app.listen(4000);
Mina as an alternative to Capistrano
For years, many Rubyists like myself have used Capistrano. I still use it but recently found out about Mina. It’s very fast. Really impressive!
The project was created by Rico Sta. Cruz and Michael Galero with the help of some other contributors.
I think I have no need to use capistrano much now. Strange how I first tried it with a Node.js app rather than a Ruby app. When I figure out multi-staging or deploying one app on multiple servers using Mina, I will try it for other apps.
Install mina. It’s a Ruby gem so if you don’t have Ruby on Rubygems, kindly look into other guides and check out RVM if you haven’t installed it yet.
gem install mina
If forever is nil
My comment so far on Node.js deployment is that it felt like the yesteryears for Ruby developers, those days without passenger and days when the sensible option was to use mongrel which some may still be using.
Without the node extension, forever, life is like this:
ps aux | grep node
ps aux | grep god
sudo kill `ps -e -o pid,command | grep god -m 1 | awk '{ print $1; }'`
sudo kill `ps -e -o pid,command | grep node -m 1 | awk '{ print $1; }'`
You can create a node-monitor script and use either god or monit or you can use forever and save a lot of time.
npm install -g forever #install forever in production server and make sure it is available globally
forever start app.js #starts the app
forever stop app.js #stops the app
forever restart app.js #restarts the app
Let’s Deploy!
To create the configuration files:
cd myapp
mina init
Replace config/deploy.rb contents with the following and edit:
require 'mina/bundler'
require 'mina/rails'
require 'mina/git'
# Basic settings:
# domain - The hostname to SSH to
# deploy_to - Path to deploy into
# repository - Git repo to clone from (needed by mina/git)
# user - Username in the server to SSH to (optional)
set :domain, 'yourdomain.com'
set :deploy_to, '/home/user/public_html/yourdomain.com'
set :repository, 'user@githost:repositoryname'
set :user, 'user'
# set :port, '30000'
desc "Deploys the current version to the server."
task :deploy do
deploy do
invoke :'git:clone'
to :launch do
queue 'forever restart app.js'
end
end
end
task :start do
queue %[cd #{deploy_to}/current && forever start app.js]
end
task :restart do
queue %[cd #{deploy_to}/current && forever restart app.js]
end
task :stop do
queue %[cd #{deploy_to}/current && forever stop app.js]
end
Deploying for the first time:
mina setup #creates the directories. This is similar to cap deploy:setup
mina deploy
mina start
Don’t worry if you get an error for the first time. After starting the app, you should get no errors.
mina deploy
Results should be something like this:
-----> Creating a temporary build path
-----> Cloning the Git repository
Initialized empty Git repository in /home/user/public_html/yourdomain.com/tmp/build-134238034110557/.git/
-----> Using revision bbeb93387e787c4491aa7a05599544a334f16e27
-----> Build finished
-----> Moving build to releases/2
-----> Updating the current symlink
-----> Launching
-----> Done. Deployed v2