Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

problem with chruby 0.3.7, capistrano v2 and assets precompiling in production #205

Open
geoffroymontel opened this Issue · 13 comments

3 participants

@geoffroymontel

Hello

I followed the WIKI to run chruby with capistrano and added these lines to my deploy.rb file.

# chruby support
default_run_options[:shell] = '/bin/bash'
set :ruby_version, "ruby-2.0"
set :chruby_config, "/etc/profile.d/chruby.sh"
set :set_ruby_cmd, "source #{chruby_config} && chruby #{ruby_version}"
set(:bundle_cmd) {
  "#{set_ruby_cmd} && exec bundle"
}

The problem is that assets are precompiled in the development environment with the default capistrano V2 recipes.

For assets precompiling, capistrano does this command

cd -- /var/www/myapp/releases/20130925065221 && RAILS_ENV=production RAILS_GROUPS=assets source /etc/profile.d/chruby.sh && chruby ruby-2.0 && exec bundle exec rake assets:precompile

and it seems that in the context of bundle exec, RAILS_ENV is not set.

I did a quick test with cap shell

cap> cd -- /var/www/myapp/releases/20130925065221 && source /etc/profile.d/chruby.sh && RAILS_ENV=production RAILS_GROUPS=assets && echo $RAILS_ENV
[establishing connection(s) to 172.16.0.2, 172.16.0.3, 172.16.0.4, 172.16.0.5]
 ** [out :: 172.16.0.2] production
 ** [out :: 172.16.0.3] production
 ** [out :: 172.16.0.4] production
 ** [out :: 172.16.0.5] production
cap> cd -- /var/www/myapp/releases/20130925065221 && RAILS_ENV=production RAILS_GROUPS=assets source /etc/profile.d/chruby.sh && chruby ruby-2.0 && exec echo $RAILS_ENV
 ** [out :: 172.16.0.2] 
 ** [out :: 172.16.0.4] 
 ** [out :: 172.16.0.5] 
 ** [out :: 172.16.0.3] 
cap> cd -- /var/www/instatube/releases/20130925065221 && RAILS_ENV=production RAILS_GROUPS=assets source /etc/profile.d/chruby.sh && echo $RAILS_ENV
 ** [out :: 172.16.0.4] 
 ** [out :: 172.16.0.2] 
 ** [out :: 172.16.0.3] 
 ** [out :: 172.16.0.5] 

Looks like sourcing chruby is causing the problem, and erasing the RAILS_ENV and RAILS_GROUPS environmment variables.

Do you know how I could fix that ?

Thanks a lot, best regards

Geoffroy

@postmodern
Owner

FOO=1 variables are only set for the first command before the &&. I'm not to knowledgeable about capistrano, so I'm not sure how to properly load chruby before executing rails commands.

@geoffroymontel

In the end, I took the code from Capistrano and adapted it to change the order of variables

So I added this code to my deploy.rb file

  namespace :assets do
    task :precompile, :roles => lambda { assets_role }, :except => { :no_release => true } do
      run <<-CMD.compact
cd -- #{latest_release} && #{set_ruby_cmd} && 
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} bundle exec rake assets:precompile
CMD

      if capture("ls -1 #{shared_path.shellescape}/#{shared_assets_prefix}/manifest* | wc -l").to_i > 1
        raise "More than one asset manifest file was found in '#{shared_path.shellescape}/#{shared_assets_prefix}'. If you are upgrading a Rails 3 application to Rails 4, follow these instructions: http://github.com/capistrano/capistrano/wiki/Upgrading-to-Rails-4#asset-pipeline"
      end

      # Sync manifest filenames across servers if our manifest has a random filename
      if shared_manifest_path =~ /manifest-.+\./
        run <<-CMD.compact
[ -e #{shared_manifest_path.shellescape} ] || mv -- #{shared_path.shellescape}/#{shared_assets_prefix}/manifest* #{shared_manifest_path.shellescape}
CMD
      end

      # Copy manifest to release root (for clean_expired task)
      run <<-CMD.compact
cp -- #{shared_manifest_path.shellescape} #{current_release.to_s.shellescape}/assets_manifest#{File.extname(shared_manifest_path)}
CMD
    end
  end
end

cheers !

@jrochkind

Hey @geoffroymontel , if you wanted to update the wiki with what you have verified to actually work, it would be appreciated!

@jrochkind

Although, wait, was the wiki written before chruby-exec, would that be a better solution now? So confused, so sad that everything ends up so complicated interdependencies.

@geoffroymontel

I need to try chruby-exec then. It's a bit late tonight but I will try this week for sure. Thanks !

@geoffroymontel

I tried chruby-exec tonight on my deploy.rb capistrano file.

I set

default_run_options[:pty] = true  # Must be set for the password prompt
                                  # from git to work
set :ssh_options, { :forward_agent => true }
set :application, "myapp"
set :repository, "git@github.com:me/myapp.git"
set :scm, :git

# chruby support
default_run_options[:shell] = '/bin/bash'

set :set_ruby_cmd, "chruby-exec ruby-2.0 --"
set(:bundle_cmd) {
  "#{set_ruby_cmd} bundle"
}

set :deploy_to, "/var/www/#{application}"

set :rails_env, :production

# user on the server
set :user, "deployer"
set :use_sudo, false

And it seems to work and compile the assets correctly.

The command executed is

  * executing multiple commands in parallel
    -> "else" :: "cd -- /var/www/myapp/releases/20131001203639 && RAILS_ENV=production RAILS_GROUPS=assets chruby-exec ruby-2.0 -- bundle exec rake assets:precompile"

My only problem is I'm getting some Warning messages every time a command involving chrubyis run

 ** [out :: 172.16.0.10] To run a command as administrator (user "root"), use "sudo <command>".
 ** [out :: 172.16.0.10] See "man sudo_root" for details.

Do you know why ? I'm not using sudo with capistrano, I have a separate user for deployment. I don't know if it can bring me troubles with permissions.

All the best

Geoffroy

@jrochkind

I don't know why, and don't even know if it's chruby or capistrano executing that (postmodern?) but I also don't understand from your description how you got capistrano to run with chruby-exec.

chruby-exec doesn't appear in any of the config you mention.

So what's making cap use `chruby-exec? Can you explain that, in case others want to follow in your footsteps?

@geoffroymontel

Sorry, bad copy & paste, I just edited my previous post.

@postmodern
Owner

I have no idea why it's complaining about sudo, but I wonder if it has something to do with use_sudo or the fact chruby-exec spawns a subshell? Have you tried running the chruby-exec command manually?

@jrochkind

Debugging error messages or unwanted consequences from capistrano recipes can be painful.

The best tool is running cap with the -d flag. That will execute each cap step one at a time, and before each one, prompt you with a y/n for if it should proceed.

Doing this, you can figure out exactly what step produces the error. Then run again, saying 'y' until you get to that step that produces the error -- then log into the server with an interactive ssh shell, and execute that next step yourself manually -- and hopefully reproduce the error! Then much about with it to figure out exactly what aspect of the command reproduces the error.

At least you can hopefully figure out what is outputting that warning message -- whether cap itself, or some command line util that cap is calling, or something else weird.

It is indeed painful. I've had to do it a few times.

@jrochkind

Oh boy, wait, just to be sure, I'm going to ask: are you running cap2 or cap3 pre-release? i have no experience with cap3, and if you are, you might want want to switch back to cap2. (Some of your pasted output doesn't look like what I've seen from cap before, which is what prompted me to ask).

You could also try asking the capistrano devs where/why that warning message would be coming from, they might know. It doesn't sound like it's likely to be coming from chruby.

@geoffroymontel

I am running capistrano 2.15.5
I will try again tomorrow night (can't ssh from work :-1:), but I am pretty sure this message is only displayed with chruby, because with my previous fix, sourcing /etc/profile.d/chruby.sh and using chruby, I did not get that message.

Thanks guys ! Will keep you posted.

@geoffroymontel

Hi

If I login to my machine with the deployer user and just try to use chruby-exec, I get the same message.

ssh -l deployer web
deployer@web:~$ chruby
 * ruby-2.0.0-p247
deployer@web:~$ which chruby-exec
/usr/local/bin/chruby-exec
deployer@web:~$ chruby-exec ruby-2.0 -- irb
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

irb(main):001:0> 

Trying to start chruby from the same command line as specified in chruby-exec

deployer@web:~$ exec "/bin/bash" -i -l -c "chruby ruby-2.0 && irb"
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

irb(main):001:0> exit

If I remove the -i option to the exec command, I don't get the error

deployer@web:~$ exec "/bin/bash" -l -c "chruby ruby-2.0 && irb"
irb(main):001:0> exit

I'm not a bash expert to understand the cause unfortunately ...

Here is my script to install chruby, run as a provisionning script of my vagrant machine (I'm pretty sure the rootuser is running this script). It's a system wide install.

#!/bin/bash
echo "Installing chruby"

wget --quiet -O chruby-0.3.7.tar.gz https://github.com/postmodern/chruby/archive/v0.3.7.tar.gz
tar -xzvf chruby-0.3.7.tar.gz
cd chruby-0.3.7/
sudo make install
cd ..
rm chruby-0.3.7.tar.gz
rm -rf chruby-0.3.7

echo "Installing ruby 2.0.0"

wget --quiet -O ruby-2.0.0-p247.tar.gz http://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p247.tar.gz
tar -xzvf ruby-2.0.0-p247.tar.gz
cd ruby-2.0.0-p247
./configure --prefix=/opt/rubies/ruby-2.0.0-p247
make
sudo make install
cd ..
rm ruby-2.0.0-p247.tar.gz
rm -rf ruby-2.0.0-p247

echo "Configuring chruby system wise"

# setup chruby system wise
sudo tee -a /etc/profile.d/chruby.sh >/dev/null <<EOF
source /usr/local/share/chruby/chruby.sh
chruby ruby-2.0
EOF

Hope it helps !

Best

Geoffroy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.