views:

18

answers:

1

I'm developing an master rails app which controls other rails apps. It has a bash script to start those rails apps, and it works well while it's invoked in the command line manually.

But if I invoke it in the matter rails app, using backticks, system, or exec, the script will fail.

The error message is:

unicorn_rails worker[0] -c ../configs/unicorns/c5.rb -E production must be run inside RAILS_ROOT:
 #<Gem::LoadError: can't activate rack (~> 1.0.0, runtime), already activated rack-1.2.1.
 Make sure all dependencies are added to Gemfile.>

And here is the bash file:

cp configs/Gemfile* $1
cd $1
bundle
bundle exec unicorn_rails -c ../configs/unicorns/$1.rb -E production

How to resolve a problem like this?

As you can see, I use bundle exec to start the child process, which should have it's own gems loaded, right?

+1  A: 

The environment variables are passed by the OS to Ruby when it loads. Ruby adds its own additional variables, then starts Rails, which adds even more.

You should be able to manipulate them by playing with the ENV hash. This will display what is defined:

ENV.each { |key, val| puts "#{ key } => #{ val }"}

You can tweak what is passed to child processes by directly modifying the ENV values then invoking the code that starts the child:

ENV['PATH'] = '/path/to/application'
ENV['PATH'] # => "/path/to/application"

Modifying the path, or stripping unwanted ENV entries to limit a child app's knowledge of the environment is pretty common.

Greg
Won't that affects the running parent process?
Cheng
It could, if you do it before the current running process has had a chance to parse ENV. If that is a concern then copy the current ENV, tweak it and spawn your child processes, then restore it. The child processes should have their own copy of the limited ENV at that point.
Greg
Cool, I found that you can simply `fork do {}` and change ENV in the `fork block` in ruby 1.9. Thank you!
Cheng
Cool. Glad that got you where you needed to be.
Greg