Indyarock

Creating Codes with Passion

rvm default ruby version not getting updated after su on ubuntu 14.04

I was working on VPS server with ruby installed via rvm. I logged in via ssh as root and did `su deployer`. Strangely, though I had set `default` ruby version as 2.1.3, I was getting 1.9.2. And if I login as deployer, I was getting the correct version.

root@localhost:/opt/nginx/conf# ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
root@localhost:/opt/nginx/conf# su deployer
deployer@localhost:/opt/nginx/conf$ ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
deployer@localhost:/opt/nginx/conf$ source ~/.bash_profile
deployer@localhost:/opt/nginx/conf$ ruby -v
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]

But if you do `su` with `-l` or `-`, it will show you the correct ruby version. The reason for this is for non-login shell, it loads .bashrc but not .bash_profile.

So including following line to .bashrc will solve the problem:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

Alternatively, you can do `su` with `-` or `-l` option.

A detailed discussion on this can be found here.

sudo: no tty present and no askpass program specified

While deployment with capistrano, I wanted to make it restart the server after deployment.

So I made following change in my deploy.rb


namespace :deploy do

  desc 'Restart application'
    task :restart do
      on roles(:app), in: :sequence, wait: 5 do
         execute "sudo /etc/init.d/nginx restart"
     end
  end

..

end

But I was getting following error while doing deployment

..
INFO[72543055] Running /usr/bin/env sudo /etc/init.d/nginx restart on 106.186.112.103
DEBUG[72543055] Command: sudo /etc/init.d/nginx restart
DEBUG[72543055] sudo: no tty present and no askpass program specified
..

I searched through some articles on net, and figured out that `deployer` user is not able to execute `/etc/init.d/nginx restart`.
To make it work, I did following changes in /etc/sudoers

# Switch to root and use visudo command instead of directly editing /etc/sudoers. This will ensure that you don't leave some garbage in this file inadvertantly.
deployer ALL = NOPASSWD: /etc/init.d/nginx

And voila, my deployment with capistrano worked 🙂

Securing database.yml while deployment using capistrano 3

I’m trying to setup capistrano since yesterday. Unfortunately I couldn’t find a single article which could guide me with whole process except this one.

Though setting up capistrano is quite easy, I was stuck at securing database.yml from committing to repository. I wanted to keep it on server side for security purpose. There were several answers on stackoverflow to use `ln -s ..`.

I also stumbled upon an image, which describes the capistrano deployment flow, which is worth mentioning.

Capistrano Execution Path

The essential key point I was missing here is, capistrano already provided `linked_files` variable, which will automatically create a softlink from shared directory.

To understand it more clearly, when we deploy with capistrano, it creates three directory inside your ‘app’ folder:


deployer@localhost:/var/www/your_own_store$ ls
releases repo shared

releases: It has different release version of your app. One release is created with one deployment.

repo: It has the actual repository cloned.

shared: It has the shared files/dir, which usually doesn’t changes with each deployment. e.g. database.yml/assets etc

So, to create a softlink just add following line to your deploy.rb file:


..
# Default value for :linked_files is []
set :linked_files, %w{config/database.yml} # <------

# Default value for linked_dirs is []
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

..

This will automatically create a softlink for your database.yml.

The point not to be missed here is: You’ll have to manually put this database.yml on your server.

Install pg gem on your machine

While install pg gem on my local mac machine, I has simply put pg gem in Gemfile.


gem 'pg', '0.17.1'

But I was getting following error:


Chandan@chandans-mbp your_own_store (master) $ gem install pg -v '0.17.1'
Building native extensions. This could take a while...
ERROR: Error installing pg:
ERROR: Failed to build gem native extension.

/Users/Chandan/.rvm/rubies/ruby-2.1.3/bin/ruby extconf.rb
checking for pg_config... no
No pg_config... trying anyway. If building fails, please try again with
--with-pg-config=/path/to/pg_config
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.

..

The reason was, I did not have install postgres database on my machine. I first install postgres from here. Then executed following command:


gem install pg -v '0.17.1' -- --with-pg-config=/Applications/Postgres.app/Contents/Versions/9.3/bin/pg_config

Please note that installing postgres creates `pg_config` in the bin directory specified in above command.

Once done, pg gem installed successfully.

Undefined method `instance’ for Capistrano::Configuration:Class

I was getting following error while setting up capistrano for deployment on VPS:

Note: I’m using capistrano 3. There is a lot of changes from capistrano 2 to capistrano 3. And 3 is not compatible with 2.


handan@chandans-mbp your_own_store (feature_add_capistrano) $ cap production check_write_rite_permissions --trace
cap aborted!
NoMethodError: undefined method `instance' for Capistrano::Configuration:Class
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/bundler-1.7.3/lib/bundler/capistrano.rb:12:in `<top (required)>'
/Users/Chandan/Workspace/personal/your_own_store/lib/capistrano/tasks/access_check.rake:1:in `require'
/Users/Chandan/Workspace/personal/your_own_store/lib/capistrano/tasks/access_check.rake:1:in `<top (required)>'
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/rake-10.3.2/lib/rake/rake_module.rb:28:in `load'
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/rake-10.3.2/lib/rake/rake_module.rb:28:in `load_rakefile'
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/rake-10.3.2/lib/rake/default_loader.rb:10:in `load'
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/rake-10.3.2/lib/rake/application.rb:760:in `load_imports'
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/capistrano-3.2.1/lib/capistrano/application.rb:48:in `load_imports'
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/rake-10.3.2/lib/rake/application.rb:695:in `raw_load_rakefile'
/Users/Chandan/.rvm/gems/ruby-2.1.3@ruby213rails4/gems/rake-10.3.2/lib/rake/application.rb:94:in `block in load_rakefile'

To fix this issue, add ‘capistrano-bundler’ gem to your Gemfile.


# Uncomment require 'capistrano/bundler' from Capfile

gem 'capistrano-bundler'

Fixed.

Install a spree application from scratch and deploy on vps

Helpful links:

Capistrano 3: http://capistranorb.com/

Full guide: http://pnhoang.tumblr.com/post/80274728962/setting-up-a-spree-commerce-site-on-a-digital-ocean

Starting nginx: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

I installed passanger and nginx on Ubuntu 14.04 LTS. While starting nginx, I was getting following error:


Starting nginx: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

This error can be caused if you have a nginx configuration that is listening on port 80 and also on port [::]:80.

$&gt; cd /etc/nginx/sites-available
$&gt; vi default
.. 
 20 server {
 21 listen 80 default_server;
 22 listen [::]:80 default_server ipv6only=on;
..
/* Remove default_server from line 21 and save */
$&gt; /etc/nginx$ sudo /etc/init.d/nginx start
Starting nginx: nginx. /*Worked */

Here is a stackoverflow link, discussing the same.

UPDATE: Incase you have done the above process and still you are getting same error, it simply means that nginx or some other process is already using port 80.
Just kill it with command below:

sudo fuser -k 80/tcp

Now try to restart your nginx server. It worked 🙂

Spree login/admin pages redirecting to with 301 response.

I just did fresh spree 2-3-stable installation on VPS. Everything looks cool, however when I try to login, the page is breaking with following production.log

I, [2014-09-21T07:05:11.320521 #12177]  INFO -- : Started GET "/login" for 123.201.138.69 at 2014-09-21 07:05:11 +0000
I, [2014-09-21T07:05:11.322632 #12177]  INFO -- : Processing by Spree::UserSessionsController#new as HTML
I, [2014-09-21T07:05:11.324725 #12177]  INFO -- : Redirected to https://106.186.112.103/login
I, [2014-09-21T07:05:11.324933 #12177]  INFO -- : Filter chain halted as #<Proc:0x00000005eaf308@/var/www/your_own_store/vendor/bundle/ruby/2.1.0/gems/actionpack-4.1.6/lib/action_controller/metal/force_ssl.rb:65> rendered or redirected
I, [2014-09-21T07:05:11.325204 #12177]  INFO -- : Completed 301 Moved Permanently in 2ms (ActiveRecord: 0.0ms)

Following changes in initializers/spree.rb will do the magic:

Spree.config do |config|
  config.allow_ssl_in_production = false #This line
end

IMPORTANT: Don’t forget to restart your server.

css and javascript not getting loaded on spree on latest build

All things set, but layout still looking too bad. All assets are not being loaded and are showing routing errors as below:

[2014-09-20T23:31:13.203461 #7482] FATAL -- :
ActionController::RoutingError (No route matches [GET] &quot;images/logo/spree_50.png &quot;):
..
..
, [2014-09-20T23:31:13.198105 #7482]  INFO -- : Started GET &quot;/javascripts/spree /frontend/all.js&quot; for 123.201.138.69 at 2014-09-20 23:31:13 +0000
F, [2014-09-20T23:31:13.199536 #7482] FATAL -- :
..
..
ActionController::RoutingError (No route matches [GET] &quot;stylesheets/spree/frontend/all.css&quot;)

It sucks when you hear that this version was bleeding edge, and it will require changes to fix. Will post update on the fix soon 🙂

UPDATE 1:
I could find something related on spree github. But when I checked my assets directory, everything looked fine,

SOLUTION:
I was not doing asset precompile:

RAILS_ENV=production bin/rake assets:precompile

That did the magic 🙂

Set environment Variable in rails.

Rails 4.0.1 has secret.yml, where the production SECRET_KEY_BASE is taken from environment hash.
This is mainly for security purpose, so that our secret key doesn’t get shared in public or other group of developers.

To generate a new secret key use:

>> rake secret
lkdsjfkldsjflkdsjfkldsjfkl

Now this secret can be set in environment variable by exporting it to .bashrc:

export SECRET_KEY_BASE='kldsfjkldsfjsdfkljdslfkj'

This did work for me, however I could find few other good approach here to do the same.