Category Archives: opensource

Reading Code

Writing documentation, is harder than writing code.

If you thought writing code is harder, my experience tells me that writing documentation even more so!

In the calculus of communication, writing coherent paragraphs that your fellow human beings can comprehend and understand is far more difficult than tapping out a few lines of software code that the interpreter or compiler won’t barf on. ~ Coding Horror

If its not documented, it doesn’t exist.

For open source projects, ‘getting started’ documentation is usually good these days. But once you run into some obscure issue or an edge case – you would have to resort to reading the code and documentation would mostly fail.

This is the time, when people are encouraged to document there finding and help out improving documentation. But as it would, code moves at a far more pace than documentation can.

Reading Code

Reading code might be an incidental task that you do while figuring out the issue with the code. But, it should actually be done as an activity of its own too. It’s widely agreed that reading great code definitely improves one’s own programming skill.

My experience while doing these ‘code reading’ exercises have been a revelation in terms of the knowledge that one can gather and the depth of the understanding.

I have realized that reading through the issues and comments listed on rails, has made me more knowledgeable with the code base than the documentation itself could ever do. Also, reading through such a huge code base like rails – is difficult to understand just by reading it. The issues and the comments / discussion on them is the best form of documentation. More like FAQs.

Smitten by this habit of reading through issues and the comments – I have decided to start *documenting* these understandings as blogpost series where I would take up the issue listed on rails/rails and then document my understanding of the behavior and summarize the comments.

Hopefully, that’s going to be helpful to all of us

– Code Reading Groups – Code is not Literature

Advertisements

Setting up Rails with Nginx + Thin on Amazon EC2 with Capistrano

1. Setting up Rails 3.2.12 on EC2 with Amazon Linux AMI

Amazon Linux AMI has Ruby 1.8.7 as default. To install ruby 1.9.3 and Rails 3.2.12 do the following

#Install ruby 1.9 by running 
sudo yum install ruby19

Note that /usr/bin might contain  ‘gem’ which actually refers to 1.8 version. So, in order to install gem1.9 do the following

sudo yum install ruby19-devel

If you do ruby -v you might still see 1.8, in order to change that,

cd /usr/bin
sudo rm ruby
sudo ln -s /usr/bin/ruby1.9 /usr/bin/ruby
sudo ln -s /usr/bin/gem1.9 /usr/bin/gem
ruby -v 
>> ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-linux] 

Now that you have ruby 1.9.3 correctly installed, we can install rails.

sudo yum groupinstall "development tools"     #(Download size: 120M !)
gem install rails --no-ri --no-rdoc
rails -v
>> Rails 3.2.12

#Also install appropriate DB that you would be using. Look here if you want to install postgresql on ec2 
#Example, if using sqlite3
sudo yum install sqlite-devel

Congratulations, you have installed Rails 3+ on your Linux AMI.

2. Installing Nginx

sudo yum install nginx

3. Install Thin

gem install thin

4. Configure Git Repository

Let’s say we want to deploy a Rails App called as  rails-demo , for that lets initialize a git-repo as

 mkdir -p ~/git/rails_demo.git
 cd ~/git/rails_demo.git
 git --bare init

This would have initialized a git repository at ~/git/rails_demo.git/ .

5. Add server keys to authorized_keys [Deployment + Git Server === EC2 Linux AMI]

We would need to do this, since Capistrano would be accessing our code-repository as if it were remote, and hence the server-keys would have to be added to its own authorized keys.

test -e ~/.ssh/id_dsa.pub || ssh-keygen -t dsa
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

6. Rails Deployment using Capistrano [Local Machine from where you want to push a rails application]

Lets say, we have a bare bones rails app created using only rails new <appname>.

rails new rails_demo
cd rails_demo
-----------------------
# Add the following to the Gemfile
gem 'capistrano'
gem 'thin'
gem 'bigdecimal'
-----------------------
# now run bundle install to install these 2 gems.
bundle install

A) Capify Deploy.rb

#In your rails application directory, run

capify . 

#[add] writing './Capfile'
#[add] writing './config/deploy.rb'
#[done] capified!

Go to deploy.rb and edit it as below. Only change the fields in bold

set :user, 'ec2-user'
set :domain, 'ec2-11-222-33-444.<region>.compute.amazonaws.com'
set :application, "rails_demo"
set :repository, "#{user}@#{domain}:git/#{application}.git"
set :deploy_to, "/home/#{user}/#{application}"
set :normalize_asset_timestamps, false

role :web, domain # Your HTTP server, Apache/etc
role :app, domain # This may be the same as your `Web` serverrole :db, domain, :primary => true # This is where Rails migrations will run
default_run_options[:shell] = false
default_run_options[:pty] = true
# miscellaneous options
set :deploy_via, :remote_cache
set :scm, 'git'
set :branch, 'master'
set :scm_verbose, true
set :use_sudo, false
# Define all the tasks that need to be running manually after Capistrano is finish
ed.
namespace :deploy do
task :bundle_install, :roles => :app do
 run "cd #{release_path} && bundle install"
 end
end
after "deploy:update_code", :bundle_install
 desc "install the necessary prerequisites"
 task :bundle_install, :roles => :app do
 run "cd #{release_path} && bundle install"
 run "cd #{release_path} && rake assets:precompile"end

*Note to change the fields in bold.

B) Thin Configuration

# Generate this thin configuration on local, which default the options to 3 thin 
# servers and production environment
thin config -C config/thin-config.yml -c ~/rails_app --servers 3 -e production

This would generate the config file with details as below. Change the chdir field to /home/ec2-user/rails_demo/current/  . (which is where the app would be deployed on ec2)

---
 chdir: /home/ec2-user/rails_demo/current/
 environment: production
 address: 0.0.0.0
 port: 3000
 timeout: 30
 log: log/thin.log
 pid: tmp/pids/thin.pid
 max_conns: 1024
 max_persistent_conns: 100
 require: []
 wait: 30
 servers: 3
 daemonize: true

C) Git Usage

Add all these files to git by doing the following

git init .
git add .
git commit -m "rails demo to ec2"
git remote add aws ssh://ec2-user@<ec2-ami-name>/~/git/rails_demo.git/
ssh-add <local-key>
git push aws master

D. Capistrano Deployment

cap deploy:setup
cap deploy:check
cap deploy

If everything goes well, take a break – you deserve it since the deployment has been done and we only need to start / configure nginx now. If you see on the deployment server there would be current directory here

/home/ec2-user/rails_demo/current  – which contains the latest deployment, we did.

7. Configuring + Starting Nginx and Thin

Now, that the application is on the server, let’s start thin and nginx.

cd /home/ec2-user/rails_demo/current 
thin start -C thin-config.yml

(This would start 3 thin instance on ports 3000 , 3001 and 3002 .)

Now, all we need to do is redirect nginx to these ports.

cd /etc/nginx 
vi nginx.conf 

and add the below content at appropriate places. I have only shown the  part to be change in bold of the http section. Only this section needs to be changed for nginx.

http {
 include /etc/nginx/mime.types;
 default_type application/octet-stream;
 server_names_hash_bucket_size 128;
 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 '$status $body_bytes_sent "$http_referer" '
 '"$http_user_agent" "$http_x_forwarded_for"';
  
access_log /var/log/nginx/access.log main;
sendfile on;
 keepalive_timeout 65;
#gzip on;
upstream thin {
 server 127.0.0.1:3000;
 server 127.0.0.1:3001;
 server 127.0.0.1:3002;
}
 
server {
 listen 80;
 server_name ec2-122-248-194-230.ap-southeast-1.compute.amazonaws.com;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
 root /home/ec2-user/rails_demo/current/public/;
 #root /usr/share/nginx/html;
 #index index.html index.htm;
# First attempt to serve request as file, then
 # as directory, then fall back to index.html
 try_files $uri $uri/ /index.html;
 # Uncomment to enable naxsi on this location
 # include /etc/nginx/naxsi.rules
 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;
 proxy_redirect off;
if (-f $request_filename/index.html) {
 rewrite (.*) $1/index.html break;
 }
if (-f $request_filename.html) {
 rewrite (.*) $1.html break;
 }
if (!-f $request_filename) {
 proxy_pass http://thin;
 break;
 } }
# redirect server error pages to the static page /40x.html
 #
 error_page 404 public/404.html;
 location = /40x.html {
 root /usr/share/nginx/html;
 }
# redirect server error pages to the static page /50x.html
 #
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 root /usr/share/nginx/html;
 }
include /etc/nginx/conf.d/*.conf;
}

Save this file, and

sudo service nginx start

Done!

Software Licensing Basics Part 2

On September 27, 1983, computer programmers logging on to the Usenet newsgroup net.unix-wizards encountered an unusual message. Posted in the small hours of the morning, 12:30 a.m. to be exact, and signed by rms@mit-oz, the message’s subject line was terse but attention-grabbing. “New UNIX implementation,” it read. Instead of introducing a newly released version of Unix, however, the message’s opening paragraph issued a call to arms:

Starting this Thanksgiving I am going to write a complete Unix-compatible software system called GNU (for Gnu’s Not Unix), and give it away free to everyone who can use it. Contributions of time, money, programs and equipment are greatly needed.

Free as in Freedom, Sam Williams

(When looking at various aspects of open source – its important to understand the backdrop which led to the creation of such licenses. ‘Free as in Freedom‘ (available online) is a wonderful read.)

… Continuing from Part 1..

1. What are the most widely used licenses?

The first version of the GPL appeared in 1988, it didn’t get too much attention until authors, including Linux creator Linus Torvalds, started using it. At this point, the realization of its implications started sinking in. For corporations, that were used to doing business on closed software – this was a truly dangerous idea.

Several derivatives of that license have evolved over this period…

Public Domain: Not really a license. But equivalent to relinquishing any rights to your code under copyright law.

BSD / MIT: Oldest and most liberal licenses available. They basically put no restrictions on how the software can be used. Ex: FreeBSD

GPL: Allow people to freely use your software as long as they don’t charge for it and use the same license for parts of the program that they wrote themselves.

LGPL: A derivative of GPL, LGPL includes an exception that is intended to allow code that is released under other licenses to co-exist with and call the LGPL code. It was meant to be a compromise between the strong copy-left GPL and permissive licenses such as the BSD licenses and the MIT License.

MPL/CDDL: MPL is used by Mozilla, Firefox, and many other projects. CDDL is based on MPL with a few minor tweaks to make it more applicable outside of Mozilla. CDDL is used by many Sun products such as Solaris. The MPL allows source code to be mixed with other files under a different license (also proprietary). However, code files licensed under the MPL must remain under the MPL and freely available in source form.

CPL/EPL: CPL was derived from the old IBM Public License and was also influenced by MPL. CPL was originally used by Eclipse, but that project switched to EPL. EPL is a newer version of CPL with some improvements in its patent language to make it more acceptable to businesses.

Dual License: This isn’t really a license, it just means making your software available under two or more different licenses.

It’s important to note a point as mentioned in slashdot comment

The GPL license is conducive to liberating software.
The BSD license is conducive to liberating people.
With the GPL license, the software maintains more of the freedom than the programmers who work on it.
With the BSD licenses, the programmers maintain more of the freedom with what they are allowed to do with derivative code.

Public Domain BSD / MIT ASLv2 (Apache) GPL (v2) LGPL MPL / CDDL CPL /EPL
Protected by copyright No Yes Yes Yes Yes Yes Yes
Can be used in closed source projects Yes Yes Yes No* Yes Yes Yes
Code using this can be commercially used Yes Yes Yes No* Yes Yes Yes
Bug Fixes, modification to be released No No No Yes Yes Yes Yes
Explicit Patent License No No Yes No (but v3 address this) No Yes Yes

2. Can I use code with those licenses – the way I want?
3. Can I derive / extend that code?
4. Would I have to make the source code available to other if I  do (3)?Comparison of License

5. As a developer how should I distribute my code?

It’s important to reason out – why are you releasing the code. Deciding that – makes the decision just a bit easier.

How Do I Choose A License? (pdf)

How Do I Choose A OSS License?

Here’s a ‘License Chooser‘ – I stumbled upon while trying to solve this license mystery myself. Hope that’s useful enough!

Recommended Further Reading

1. On the Decline of GPL

2. Choosing a license for FOSS

3. OSS License . How to pick and OSS License Part 1 Part 2

4. Comparison of open source licenses

5. Choosing a License and Applying It (eBook)

6.