I'm trying to deploy a Ruby on Rails application using nginx and unicorn. When I try to run my unicorn init script, I get the following error:
$ sudo service rails_app start
Starting rails_app
-su: bundle: command not found
It fails to run on this command:
su - complab -c "bundle exec unicorn -c config/unicorn.rb -E production -D"
However, running unicorn manually while logged in as $USER
works just fine:
$ bundle exec unicorn -c config/unicorn.rb -E production
I have verified that the path set on the init script is correct. On further investigation, I discovered that while $USER
has ruby version 2.2.0 installed via rbenv, running su - $USER -c "ruby -v"
shows that it's running on 1.9.3.
I have already run rbenv global 2.2.0
but still it doesn't work.
I thought su
meant I was able to temporarily changing the user who owns the session? Why is it that su $USER
shows a different ruby version from when I am actually logged in as $USER
?
Hope you can help me out!
The reason is that sudo
doesn't preserve environment variable. And since rbenv
is using user environment it doesn't work out of the box. You can use a command like this to run ruby with sudo
:
ruby=`which ruby` && sudo $ruby -v
If you want to run unicorn
under the user you have installed rbenv
into you have to change these to match your app:
!/bin/sh
### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts unicorn
# Description: starts uniconr using start-stop-daemon
### END INIT INFO
set -u
set -e
export PATH=/path/to/rbenv/bin:$PATH
export RBENV_DIR=/path/to/rbenv
export RBENV_ROOT=/path/to/rbenv
APP_ROOT=/path/to/rack_app/root
PID=$APP_ROOT/tmp/pids/unicorn.pid
RAILS_ENV=production
export PATH="$RBENV_ROOT/shims:$RBENV_ROOT/rbenv:$PATH"
CMD="bundle exec $RBENV_ROOT/shims/unicorn -D -E $RAILS_ENV -c config/unicorn/$RAILS_ENV.rb"
old_pid="$PID.oldbin"
cd $APP_ROOT || exit 1
sig () {
test -s "$PID" && kill -$1 `cat $PID`
}
oldsig () {
test -s $old_pid && kill -$1 `cat $old_pid`
}
case $1 in
start)
sig 0 && echo >&2 "Already running" && exit 0
$CMD
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
$CMD
;;
upgrade)
sig USR2 && exit 0
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
;;
rotate)
sig USR1 && echo rotated logs OK && exit 0
echo >&2 "Couldn't rotate logs" && 1
;;
*)
echo >&2 "Usage $0 <start|stop|restart|upgrade|rotate|force-stop>"
exit 1
;;
esac