Tuesday, 16 September 2014

Configure Nginx with Unicorn on Ubuntu(Linux)

Introduction

So finally you choose to go with NginxUnicorn for your rails application.  Thats great!
We will go through with all the aspect for deploying your app on cloud. For sake of hand we will use AWS's EC2 server for deployment as it is mostly used.


Prepare your instance & Install dependent libraries

When you purchase the instance it is almost blank except OS installed. So we need to prepare it for our deployment. Lets install them first.

$ sudo apt-get update
$ sudo apt-get install build-essential git-core
$ sudo apt-get install zlib1g-dev libssl-dev

Also install vim as you will need it when updating config files on server.

$ sudo apt-get install vim

Install Nginx

Lets install Nginx.

$ sudo apt-get install nginx

It should installed nginx at /etc/nginx . Inside that directory you will find nginx.conf which main config file for Nginx. We will talk more about it later.

Install Ruby

Now its time to install ruby.

Follow the instruction to install RVM at https://rvm.io/rvm/install . There are 2 ways to install rvm
1) Single User installation
2) Multi User installation

I would suggest to go with Multi user installation. You just need to add any user to role "rvm" whom you wanted to give access to use rvm.


Unicorn

Copy below code to unicorn.rb under /config directory of your project. 



# Sample verbose configuration file for Unicorn (not Rack)
#
# This configuration file documents many features of Unicorn
# that may not be needed for some applications. See
# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
# for a much simpler configuration file.
#
# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
# documentation.

# WARNING: See config/application.rb under "Relative url support" for the list of
# other files that need to be changed for relative url support
#
# ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"

# Read about unicorn workers here:
# http://doc.gitlab.com/ee/install/requirements.html#unicorn-workers
#
worker_processes 3

# Since Unicorn is never exposed to outside clients, it does not need to
# run on the standard HTTP port (80), there is no reason to start Unicorn
# as root unless it's from system init scripts.
# If running the master process as root and the workers as an unprivileged
# user, do this to switch euid/egid in the workers (also chowns logs):
# user "unprivileged_user", "unprivileged_group"

# Help ensure your application will always spawn in the symlinked
# "current" directory that Capistrano sets up.
working_directory "/path/to/your/project" # available in 0.94.0+

# Listen on both a Unix domain socket and a TCP port.
# If you are load-balancing multiple Unicorn masters, lower the backlog
# setting to e.g. 64 for faster failover.
listen "/path/to/your/project/tmp/sockets/unicorb.socket", :backlog => 1024


# nuke workers after 30 seconds instead of 60 seconds (the default)
#
# NOTICE: git push over http depends on this value.
# If you want be able to push huge amount of data to git repository over http
# you will have to increase this value too.
#
# Example of output if you try to push 1GB repo to GitLab over http.
#   -> git push http://gitlab.... master
#
#   error: RPC failed; result=18, HTTP code = 200
#   fatal: The remote end hung up unexpectedly
#   fatal: The remote end hung up unexpectedly
#
# For more information see http://stackoverflow.com/a/21682112/752049
#
timeout 60

# feel free to point this anywhere accessible on the filesystem
pid "/path/to/your/project/tmp/pids/unicorn.pid"

# By default, the Unicorn logger will write to stderr.
# Additionally, some applications/frameworks log to stderr or stdout,
# so prevent them from going to /dev/null when daemonized here:
stderr_path "/path/to/your/project/log/unicorn.stderr.log"
stdout_path "/path/to/your/project/log/unicorn.stdout.log"
# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true

# Enable this flag to have unicorn test client connections by writing the
# beginning of the HTTP headers before calling the application.  This
# prevents calling the application for connections that have disconnected
# while queued.  This is only guaranteed to detect clients on the same
# host unicorn runs on, and unlikely to detect disconnects even on a
# fast LAN.
check_client_connection false

before_fork do |server, worker|
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!

  # The following is only recommended for memory/DB-constrained
  # installations.  It is not needed if your system can house
  # twice as many worker_processes as you have configured.
  #
  # This allows a new master process to incrementally
  # phase out the old master process with SIGTTOU to avoid a
  # thundering herd (especially in the "preload_app false" case)
  # when doing a transparent upgrade.  The last worker spawned
  # will then kill off the old master process with a SIGQUIT.
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
  #
  # Throttle the master from forking too quickly by sleeping.  Due
  # to the implementation of standard Unix signal handlers, this
  # helps (but does not completely) prevent identical, repeated signals
  # from being lost when the receiving process is busy.
  # sleep 1
end

after_fork do |server, worker|
  # per-process listener ports for debugging/admin/migrations
  # addr = "127.0.0.1:#{9293 + worker.nr}"
  # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)

  # the following is *required* for Rails + "preload_app true",
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection

  # if preload_app is true, then you may also want to check and
  # restart any other shared sockets/descriptors such as Memcached,
  # and Redis.  TokyoCabinet file handles are safe to reuse
  # between any number of forked children (assuming your kernel
  # correctly implements pread()/pwrite() system calls)
end

You can change "worker_processes" and "timeout" according to your app and sever config.

Configure Nginx to use Unicorn


Now time to configure Nginx. Create a file yoursite.com in "/site-available" directory under nginx's home directory(/etc/nginx) .


upstream your_app {
    # Path to Unicorn SOCK file, as defined previously
    server unix:/path/to/your/project/tmp/unicorn.sock fail_timeout=0;
}

server {


    listen 80;
    server_name yoursite.com;

    # Application root, as defined previously
    root /path/to/your/project/public;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://your_app;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}  


Please make sure to match socket path of unicorn. It should match with what you have defined in unicorn.rb .


Time to start Unicorn

Every thing is setup. Now time to start Unicorn. From root of your application directory run below command. Don't forget to adjust environment if you are running in staging or anyother environment.


bundle exec unicorn_rails -c config/unicorn.rb -E production -D


At this point your site is setup and running now. Go to yoursite.com .

Monday, 15 September 2014

Commands for exporting and importing database from postgresql

To export data:
pg_dump -U username -Fc database_name > db_backup.dump


To import data:
pg_restore --verbose --clean --no-acl --no-owner -d database_name db_backup.dump

Tuesday, 9 September 2014

Setting hosts on ubuntu and windows 7


Setting hosts on ubuntu :


Setting host on ubuntu is pretty straight forward. You just need to have sudo user permission to do so.

Type below command (using gedit as editor):

sudo gedit /etc/hosts

It will open hosts file and you can make your changes there.


Using vim editor :

sudo vi /etc/hosts

Setting hosts on Windows 7:


It's very complex to set hosts in windows 7 although you have all administrator rights. Windows restrict you to make any changes in your hosts file. 

We don't need to make any permission changes in hosts file (Some time we may forgot to change file permission again to it's original permissions). So first of all we will start with finding the hosts file.

The path to the Hosts file in Windows 7 is the same as usual. open start menu and run :

%systemroot%\system32\drivers\etc\

This will open etc folder in which you find hosts file. You can manually find hosts file also.

C => Windows  => System32 => drivers => etc => hosts

Follow below steps :

- Before doing anything create a backup of your hots file.
- Separate copy hosts file to any other location on system (I prefer on desktop).
- Make changes in new file that we have on desktop.
- Replace original hosts file with new one that we have on desktop.
- Restart your system (Not mandatory)

We are done :)


Monday, 8 September 2014

Configure Ubuntu 12.04 for Ruby On Rails development


What is "Ruby On Rails"?


Ruby is a programming language and rails is a software library that extends the Ruby programming language. David Heinemeier Hansson is creator of rails. He gave it the name "Ruby on Rails" though it is often just called "Rails."

Install Ruby with RVM


To make sure our all the package that we are going to install are upto date. We should run a quick update. Open terminal and type command:

sudo apt-get update

Once we have done with update. We will start installing RVM (Ruby Version Manager). RVM is a great tool to manage multiple versions of ruby on single machine.

In this blog we will going to use curl to install RVM.

If you don't have curl on your system, then type command:

sudo apt-get install curl

After you finish with curl. Install rvm using following command:

\curl -L https://get.rvm.io | bash -s stable

After installation finished, load RVM. You may need to exit out of your terminal and start up a new one. To load RVM :

source ~/.rvm/scripts/rvm

RVM has some of its own dependancies that need to be installed. To automatically install them:

rvm requirements

You are done with rvm. Now installing ruby is easy.

rvm install ruby-2.x.x
rvm install ruby-1.9.x

And so on. Using specific version as default.

rvm install ruby-2.x.x --default

Sometime you may get following error:

RVM is not a function, selecting rubies with 'rvm use ...' will not work.

You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.
 

Answer for error is in error itself. go here and make desired changes and you are done.

Now next we makes sure that we have all the required components of Ruby on Rails. So we continue to install rubygems (By default RVM already installed gems for current version). 

rvm rubygems current

Once everything is set up, it is time to install Rails. 

gem install rails

This process may take a some time, be patient. Now we have Ruby On Rails on our machine.

For different requirement we need different database. So now we start with PostgreSQL setup. By default sqlite used as database in rails.

 

Install PostgreSQL:


To download Postgres and its helpful accompanying dependencies:

sudo apt-get install postgresql postgresql-contrib

You are done with postgres installation.

Create database user(Role):

Postgres uses the concept of roles to distinguish the variety of users that can connect to a database. When it is first installed on a server, the default postgres user is actual named “postgres”. 

To create custom user, first switch into the default user:

sudo su – postgres

Now create new role(user) in PostgreSQL system :

createuser

It will propmpt you as follow :

Enter name of role to add: newuser
Shall the new role be a superuser? (y/n) y

If you want to set password for newly created Role(User) then command should be:

createuser --pwprompt


Install MySQL:


installtion of MySQL on ubuntu is pretty simple. Open command promt and type :

sudo apt-get install mysql-server

During installation process MySQL will ask you to set a root password. Set your root password and you are done.

Now we have fully configured machine with RVM, PostgreSQL and MySQL for rails development.

CREATE EXTENSION hstore getting error

Log:
-------------------------------------------------------------------------------------------------------------------
-- execute("CREATE EXTENSION hstore")
rake aborted!

StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedFile: ERROR:  could not open extension control file "/usr/share/postgresql/9.1/extension/hstore.control": No such file or directory
: CREATE EXTENSION hstore/usr/local/rvm/gems/[email protected]/gems/activerecord-4.1.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `async_exec'
--------------------------------------------------------------------------------------------------------------------

Solution:

If you have postgresql already installed then run below command

$ sudo apt-get install postgresql-contrib


Friday, 5 September 2014

SETTING UP A CLOUDFRONT CDN FOR RAILS

The Problem:

Even with the asset pipeline, content is transmitted to the end user over their, sometimes slow, connection. Distance plays a role in the speed at which data can be delivered. Because of this, users further away from your servers get a sluggish experience. This decreases both the users’ patience and your ability to effectively engage them.


The Solution:

CDNs are networks of servers that host your content so that when you make a request, the request is served from a server closest to you. This can often reduce transmission time by several seconds (…think users in Asia requesting content that’s served from Virginia – this is the case if you deploy to Heroku).

The use of a CDN also reduces the number of requests to your application servers. Most Ruby applications use Nginx or Apache in front of the Ruby processes. These HTTP servers are really good at serving static content, but no one will deny – the fewer requests, the better.

Option 1: Push your assets to the CDN during deployment

Depending on your method of deployment, pushing assets to a CDN isn’t always trivial. The asset_sync gem has made this relatively straight forward if you choose to host your assets from Amazon S3. Out of the 2 options, this is the most efficient because all requests for assets will be diverted away from your application, leaving its precious processing power to serve more important application requests.

Option 2: Assets are pulled to the CDN on first request

This option won’t change deployment and is simple to setup. The only downside is that upon first request to an asset, the CDN will pull it from your web server and cache it (it’s hardly a downside if you’re currently serving all your assets from your web server). All subsequent requests to that asset will be served straight from the CDN. The simplicity of this option generally makes it my preferred option.

So let’s get to it…




Amazon Cloudfront:

Log in to your Amazon EC2 account and click “Cloudfront”:

"Click Cloudfront in the AWS web console"


Click “Create Distribution”:

"Create a Cloudfront distribution endpoint"

Enter the domain where your assets currently live (ignore Origin ID – it’ll be filled in for you):

"Settings for a typical CDN"


Make note of the Cloudfront distribution URL

"Cloudfront distribution URL"

In Rails application:


Rails provides and easy way to change the host URL of the assets (images, stylesheets, javascripts, fonts…). Enter the Cloudfront distribution URL from above as the Rails asset_host.

# config/environments/production.rb
config.action_controller.asset_host = "d24xjtg100euk4.cloudfront.net"
At this point, the domain of all Rails asset helpers image_tag, stylesheet_link_tag, and javascript_include_tag will be prefaced with the asset host URL that you configured above.

For example:

image_tag("shark_teeth.png")
# http://d24xjtg100euk4.cloudfront.net/assets/images/shark_teeth.png
Note: if you only change config/environments/production.rb, you won’t see any changes in your development environment.

And that’s it!



In AngularJS, how would you cache the data (for example, a list of top 10 news of today) you receive from Java?


I am fetching the list of news from the Backend and want to cache them and display them in HTML5 using the AngularJS.

I am new to Angular and don't know the correct way to do this. is it possible to cache this data or not. Please suggest.


Thursday, 4 September 2014

conditional multiplication of rates as per increase count

What is best approach and coding practice for my below requirements:
As I have user records in my table, and I want to charge user as per conditional basis
Condition is, If user has 20 record then system will charge by 500 USD per record If user has 30 record then System will charge then system will charge 500 USD per record for 20 records and 300 USD for next 10 records also If user has more than 30 records then charges then calculation will be (20 * 500 + 10 * 300 + addition-records * 100 )

Record Table

Post(:id, :content, :user_id)

I have also subscription table where I manage charges
I will appreciate If coders will uses constant for static values, like
$ {1 to 20 => 500, 20 to 30 => 300, 30 to x => 100 } ...etc

Wednesday, 3 September 2014

Rename Database Column in a Rails Migration

rename_column :table_name, :old_column_name, :new_column_name
Rails g migration ChangeColumnName
# creates  db/migrate/xxxxxxxxxx_change_column_name.rb

# db/migrate/xxxxxxxxxx_change_column_name.rbclass ChangeColumnName < ActiveRecord::Migration
  def self.up
    rename_column :table_name, :old_column, :new_column
  end

  def self.down
    # rename back if you need or do something else
  end
end

Tuesday, 2 September 2014

Install postgres on ubuntu 12.04

postgresql is a powerful and reliable object-relational database system. it’s a great alternative for mysql. it is as easy to set up, performs better and offers far more features.

1. make sure you already have install python-software-properties
     $sudo apt-get install python-software-properties

2.add ppa repository to my ubuntu.
     $sudo add-apt-repository ppa:pitti/postgresql

3. after adding ppa, update your system apt:
     $sudo apt-get update

4.finally install postgresql-9.1:
     $sudo apt-get install postgresql

   if you having any error, make sure you already  install libpq-dev.the libpq-dev package is for compiling   wrappers/clients against libpq.
     $sudo apt-get install postgresql-9.1 libpq-dev

5.now check it out installation is successful or…..
     $ locate postgresql

6. if done!!!, cheers …………..   check the install version.
     $psql -v

7. now let’s take look to postgres console. if you are login as root user
     $su postgres

   for other user    
     $ sudo su postgres -c psql
   now you are on postgres console

Adding the existing application on heroku and deploying on heroku

$ git remote add heroku [email protected]:name of app on heroku

$ ssh-keygen -t rsa -c "garuav[at]gmail.com" -f ~/.ssh/id_rsa_heroku

then added to my machine

$ ssh-add ~/.ssh/id_rsa_heroku

and, finally, to heroku

$ heroku keys:add ~/.ssh/id_rsa_heroku.pub

after that,

$ git push heroku master

Validating uniqueness of nested model with parent_id

I recently came across to an interesting issue where I setup a uniqueness validator on a field, with a scope on the parent's Id. And Thought that is should work for me, This was fine for updating with an existing parent, but if I ever created two or more new fields, the validation would fail because there was no ID on the parent model yet for the child to validate against.

class Child < ActiveRecord::Base
    belongs_to :parent 
    validates :value, :uniqueness => { :scope => :parent_id }
end

class Parent < ActiveRecord::Base 
  has_many :children 
  accepted_nested_attributes_for :children 
end

Here is the code snippet that will solve the issue and allow you to validate uniqueness of nested model on create as well as on update.

class Child < ActiveRecord::Base 
  belongs_to :parent
  validates :value, :uniqueness => { :scope => :parent_id } 
end   

class Parent < ActiveRecord::Base 
    has_many :children 
    accepted_nested_attributes_for :children   
    validate :uniqueness_of_children 

private   

  def uniqueness_of_children 
    hash = {} 
    children.each do |child|
      if hash[child.value]
        errors.add(:"text", "error") if errors[:"text"].blank? 
        child.errors.add(:value, "has already been taken") 
      end
      hash[child.value] = true 
    end 
  end

end

Steps for creating gem

Example

 

Just to make sure you have bundler gem installed. 
  • $ gem install bundler
Now as bundler is installed, you just need to choose name for your gem, in this case "gem-post".
  • $ bundle gem gem-post
This creates the "gem-post" directory with following gem structure :
  • $ tree gem-post
    gem-post
    ├── .gitignore
    ├── Gemfile
    ├── LICENSE.txt
    ├── README.md
    ├── Rakefile
    ├── gem-post.gemspec
    └── lib
        ├── gem-post
        │   └── version.rb
        └── gem-post.rb
Let's first look at the gemspec file (gem-post.gemspec in this case). This file contains metadata about the gem, such as the name, description, author, license, and any gem dependencies required for it to work.

  • # coding: utf-8
    lib = File.expand_path('../lib', __FILE__)
    $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
    require 'dogeify/version'
    
    Gem::Specification.new do |spec|
      spec.name          = "gem-post"
      spec.version       = GemPost::VERSION
      spec.authors       = ["Author Name"]
      spec.email         = ["[email protected]"]
      spec.description   = %q{A short description!}
      spec.summary       = %q{A short description!}
      spec.homepage      = ""
      spec.license       = "MIT"
    
      spec.files         = `git ls-files`.split($/)
      spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
      spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
      spec.require_paths = ["lib"]
    
      spec.add_dependency 'engtagger'
    
      spec.add_development_dependency 'bundler', '~> 1.3'
      spec.add_development_dependency 'rake'
      spec.add_development_dependency 'rspec'
    end
Now, just take a look at lib/gem-post.rb and lib/gem-post/version.rb files. These two files are initially very simple.

First start with version.rb :
  • module GemPost
      VERSION = "0.0.1"
    end
This file contains only the version number.

Now, look at the gem-post.rb :
  • require "gem-post/version"
    
    module GemPost
      # This is the place, where you will put your GEM code.
    end
Replace comment with your GEM code.

And, thats it, you are ready with your first gem to be released.

How to release a GEM


  • Prerequisites :
  1. You must commit your GEM files to GIT, as Bundler assumes that you're working with some sort of git repository.
  2. You must have an account on rubygems.org in order to release your gem.

Now, as you have both the prerequisites setup, you can simply run :
  • $ bundle exec rake release
This will release your gem, which will accessible through rubygems.org.

As its been released now, you can add this "gem-post" gem into your Gemfile.


Updating GEM

  1. Make changes into your GEM code,
  2. Update the version in lib/gem-post/version.rb file, 
  3. Make a commit of your changes, and run : 
    • $ bundle exec rake release
 Updated gem version will be relesed on rubygems.org and will be available to use it into your Gemfile.