meyagen meyagen - 3 months ago 13
Ruby Question

Why is su using a different ruby version compared to when I'm logged in as the actual user?

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!

Answer

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