Reputation: 190859
I'm trying to start the rails app when Ubuntu starts up.
For this, I added these lines in /etc/rc.local
.
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
bundle exec passenger start --port 8000 --user ubuntu --daemonize
However, the rc.local
exits with error
+ cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
+ bundle exec passenger start --port 8000 --user ubuntu --daemonize
/usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:92:in `block in materialize': Could not find rake-10.4.2 in any of the sources (Bundler::GemNotFound)
from /usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:85:in `map!'
from /usr/lib/ruby/vendor_ruby/bundler/spec_set.rb:85:in `materialize'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:114:in `specs'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:159:in `specs_for'
from /usr/lib/ruby/vendor_ruby/bundler/definition.rb:148:in `requested_specs'
from /usr/lib/ruby/vendor_ruby/bundler/environment.rb:18:in `requested_specs'
from /usr/lib/ruby/vendor_ruby/bundler/runtime.rb:13:in `setup'
from /usr/lib/ruby/vendor_ruby/bundler.rb:120:in `setup'
from /usr/lib/ruby/vendor_ruby/bundler/setup.rb:17:in `<top (required)>'
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
The error is caused from using the ruby installed from rbenv; the ruby is in /home/ubuntu/.rbenv/bin/ directory. I guess when ubuntu starts up, the system ruby is executed, but it does not know anything about installed packges with rbenv's ruby and gem.
How can I solve this issue? Is there any way to make the ruby from rbenv as system's ruby?
For getting the error, I used the hints from this post: Run script with rc.local: script works, but not at boot.
mwp's answer works fine, but I think I'd better make things clearer.
Run bundle --deployment --binstubs
to create ./vendor and copy files in bundle directory.
#!/bin/bash
export APP_ROOT="/home/ubuntu/webapp/rails/passenger-ruby-rails-demo"
export APP_USER="ubuntu"
export APP_PORT="8000"
export RBENV_ROOT="/home/ubuntu/.rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# Assuming you installed bundle with --binstubs...
$APP_ROOT/bin/passenger start --port $APP_PORT --user $APP_USER --daemonize
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
sh ./setup.sh
exit 0
Upvotes: 0
Views: 287
Reputation: 190859
Upstart (http://upstart.ubuntu.com) can be a better way to replace rc.local.
# simple script
# http://uwsgi-docs.readthedocs.org/en/latest/Upstart.html
description "passenger "
start on runlevel [2345]
stop on runlevel [06]
respawn
# http://stackoverflow.com/questions/14823972/upstart-node-js-working-directory
script
chdir /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
exec sh runme.sh
end script
Upvotes: 0
Reputation: 8467
Run these commands one time:
cd /home/ubuntu/webapp/rails/passenger-ruby-rails-demo
rbenv local <the version you want>
This will create a .ruby-version
file in your application directory that tells rbenv which version to use.
I would also recommend that when you deploy the application to its "production" location, you install bundler with the --deployment --binstubs
flags. This will install the Gems inside a vendor
subdirectory (to insulate them from an errant Gem update) and create handy shortcuts inside a bin
subdirectory to run e.g. passenger
, rackup
, etc. without needing to do bundle exec
.
However, you have another problem, and that is that rbenv
(the shell function) [probably] isn't available while rc.local
is running. I would recommend creating a new shell script and stashing it somewhere, possibly within your application's directory structure, with (something like) the following contents:
#!/bin/bash
export APP_ROOT="/home/ubuntu/webapp/rails/passenger-ruby-rails-demo"
export APP_USER="ubuntu"
export APP_PORT="8000"
export RBENV_ROOT="/path/to/rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# Assuming you installed bundle with --binstubs...
"$APP_ROOT"/bin/passenger start --port $APP_PORT --user $APP_USER --daemonize
Then mark this script executable and you can call it from rc.local to start the service. As far as what you set RBENV_ROOT
to, you can either use an existing user's .rbenv
directory (e.g. ~ubuntu/.rbenv
, assuming you installed a copy there), or you can set up a system-wide rbenv at /opt/rbenv
or elsewhere. There are some good notes here.
I can think of a million different ways to improve the above script, and indeed this is only one of a million different ways to tackle this problem. Starting and stopping services is quite a hot topic in the DevOps and SysAdmin communities right now. I've had great success running Ruby applications in production using rbenv and Bundler, and if you decide to go this route, I hope you will too!
Upvotes: 1