capistrano

Capistrano: uploading / downloading directory to / from remote server via SCP or sftp

Hey I found two interesting functions while going through capistrano’s files. There are two functions named “upload” and “download”, which can be used to download and upload directories from / to remote server using scp.

Examples:

upload(“LOCAL_DIR_PATH”, “REMOTE_PATH”, :via=> :scp, :recursive => true)

download(“REMOTE_PATH”, “LOCAL_DIR_PATH”, :via=> :scp, :recursive => true)

You can also use :sftp.

Unfortunately it is not much documented :( .

Presented at BarCampDelhi3

Yesterday, I attended third barcamp in delhi. I presented a session “Deploying rails application in EC2″. It was an amazing experience. We talked about EC2 and I had given a demo “How to deploy rails application on EC2″.

I personally didn’t like some sessions. There were people from some company and after every 2 mins they were saying “we are the best”. I think this should not happen in barcamp. As far as I know about barcamp, it is for sharing your experiences, talking about new technology, but not for promoting your company.

I think that, at BarCamp there should be sessions on new things, not on the things that are popular and have similar other services.

There was a very good session by Jinesh Varia on Amazon Cloud Computing. He included Amazon’s simple storage system, and Amazon’s cloud computing(Ec2) in his presentation. He also helped me in answering people while the demo. He gave me a hint that very soon there will a news from Amazon that will surprise us.

I have uploaded my presentation slides on Slideshare.net:

Thanks to Impetus Noida for Hosting Barcamp for second time and Opera for Beer.

Stuck with capistrano

I was deploying my latest code to live site today using Capistrano, and suddenly I stuck. When I tried to deploy the code, it checked out the latest version on the server and while executing after_symlink task it rolled back. I was surprised because the deploy script was working fine earlier and I haven’t made any change in deploy.rb or deploy procedure. I tried many times but not succeed, and then I found the root of problem.

The problem was that I mistakenly created a file in releases directory and Capistrano uses ln -x1 command to create symbolic link to current release. And Capistrano links last output of ‘ln -x1′ as ‘current’, so in this case ‘current’ was linking to a file. This was doing all the mess, as ‘current’ was pointing to a file instead of latest release directory. I deleted that file from releases and then it worked fine…

apache proxy balancer + mongrel clusters and deploying application with capistrano

So you want to setup production server with mongrel clusters and apache proxy balancer, also wants to use capistrano for deployment, huh. Take it easy, its very simple.

You need Apache 2.2 or later on your production server, and the following ruby gems on your both machine(server and local):

  • capistrano
  • mongrel
  • mongrel_cluster

I haven’t mentioned rails and rake gem as we are deploying a rails application so these gems are obvious.

Lets install above gems (if not installed) by issuing:

gem install –include-dependencies capistrano
gem install –include-dependencies mongrel
gem install –include-dependencies mongrel_cluster

Now make sure that the following modules are enabled (they are disabled by default) :

  • mod-rewrite
  • mod-proxy
  • mod-proxy-http
  • mod-proxy-balancer

to check if they are enabled issue ” /etc/init.d/apachectl -M ” on server, it will list all the enabled modules. For Debian systems all enabled modules are in /etc/apache2/mods-enabled directory and all available modules are in /etc/apache2/mods-available directory, to enable them issue ” a2enmod MOD_NAME “.

Now create the production database(on server) and update database.yml for production database settings.

After this configure mongrel by issuing ” mongrel_rails cluster::configure -e production -p 8000 -a 127.0.0.1 -N 2 -c ./ ” inside the rails application root directory(on client machine). This will create mongrel_cluster.yml in config directory. You can change parameters in this command, as -p 8000 specifies that mongrel instances will start up on port number starting 8000, -a 127.0.0.1 specifies that mongrel instances will listen to the localhost, -N specifies the number of mongrel instances and -c specifies the rails root directory.

Now its time to capistranize rails application, issue ” cap –apply-to ./ APP_NAME ” inside rails application root directory(on client machine), this will add two files(config/deploy.rb and lib/tasks/capistrano.rake) to the rails application. Edit deploy.rb according to your requirements. Also add the following code to deploy.rb :

task :restart, :roles => :app do
# stop mongrel clusters for previous release and start for current
run “cd #{previous_release} && mongrel_rails cluster::stop”
run “sleep 5″
run “cd #{current_release} && mongrel_rails cluster::start”
end

Now on your local machine issue these two commands in only once ” rake remote:setup ” and ” rake remote:cold_deploy “, when you issue ” rake remote:setup ” it will prompt for the server password and create necessary directories on the server and ” rake remote:cold_deploy ” will deploy your code to the server. Next time whenever you want to deploy to the server you just need to issue ” rake remote:deploy ” not ” rake remote:cold_deploy “.

Now we are just one step back, we need to configure apache proxy balancer for mongrel instances. Add the following code to the httpd.conf file:

BalancerMember http://127.0.0.1:8000
BalancerMember http://127.0.0.1:8001


ServerName myapp.com
DocumentRoot /rails_apps/app/public


Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]

RewriteRule ^/$ /index.html [QSA]
# Rewrite to check for Rails cached page
RewriteRule ^([^.]+)$ $1.html [QSA]

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]

you need to change the above code according to you requirement. Also you need to restart apache server by issuing ” /etc/init.d/apachectl restart “. Now you are done.

But we also need to add a script to start mongrel instances when the server restarts, otherwise whenever the server restart there will no mongrel instance running.

Just create a file named mongrel_clusters (you can choose any name) in /etc/init.d directory with the following code:

#!/bin/bash
#
# chkconfig: 345 94 16
# description: Startup script for mongrel
BASEDIR=/var/www/your_app
export HZ=100
export TERM=linux
export SHELL=/bin/bash
export HUSHLOGIN=FALSE
export USER=root
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
export MAIL=/var/mail/root
export _=/usr/bin/env
export PWD=/etc/init.d
export HOME=/root
export SHLVL=2
export LOGNAME=root

cd $BASEDIR
case “$1″ in
start)
echo “starting up mongrel in $BASEDIR”
mongrel_rails cluster::start
;;
stop)
echo “stopping mongrel”
mongrel_rails cluster::stop
;;
restart)
mongrel_rails cluser::stop
sleep 3
mongrel_rails cluster::start
;;
esac

You need to change the BASEDIR in the above code. Make this file executable by ” chmod +x /etc/init.d/mongrel_clusters
Issue these commands to add this script at system startup:

Debian: /usr/sbin/update-rc.d /etc/init.d/mongrel_clusters defaults
RedHat: /usr/sbin/chkconfig –add /etc/init.d/mongrel_clusters and /usr/sbin/chkconfig –level 2 /etc/init.d/mongrel_clusters on

Note: Use above instructions at your own risk, if your computer explodes its not my fault :-)