问题
I recently created a VPS on DigitalOcean to host a rails app. I followed their guide to setup Unicorn with my application. https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04
A problem occurred when I ran sudo service unicorn_appxyz start
. The error given was -su: bundle: command not found
I traced the init.d script and pasted the evaluated server start up command in terminal and it works fine when executed under the user joe (the user which rbenv is install and the owner of the app). The evaluated command is
su - joe -c cd /home/joe/appxyz && bundle exec unicorn -c config/unicorn.rb -E production -D
I then sudo su - into root user and ran service unicorn_appxyz start
the error was of course the same. Then I ran the evaluated command under root and it return with this error
The program 'bundle' is currently not installed. You can install it by typing:
apt-get install bundler
It seems the script is not switching the user? This is likely the cause of unicorn not starting when i boot my VPS.
The full unicorn upstart script is here:
#!/bin/sh
### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the unicorn app server
# Description: starts unicorn using start-stop-daemon
### END INIT INFO
set -e
USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
# app settings
USER="joe"
APP_NAME="appxyz"
APP_ROOT="/home/$USER/$APP_NAME"
ENV="production"
# environment settings
PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"
# make sure the app exists
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
echo "Starting $APP_NAME"
su - $USER -c "$CMD"
;;
stop)
echo "Stopping $APP_NAME"
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
echo "Force stopping $APP_NAME"
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload|upgrade)
sig USR2 && echo "reloaded $APP_NAME" && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
$CMD
;;
rotate)
sig USR1 && echo rotated logs OK && exit 0
echo >&2 "Couldn't rotate logs" && exit 1
;;
*)
echo >&2 $USAGE
exit 1
;;
esac
More related info
here are the paths for ruby, rails and bundler under user joe. Under root they are not found.
joe@vps:~$ which ruby
/home/joe/.rbenv/shims/ruby
joe@vps:~$ which rails
/home/joe/.rbenv/shims/rails
joe@vps:~$ which bundle
/home/joe/.rbenv/shims/bundle
It make sense bundler could not be found under root user but the upstart command should have switched to user 'joe' to run the bundle command. This is the part I don't understand.
回答1:
I found out the issue. Explanation follows,
root user on startup will first su - into the rails user (in this case 'joe') then executes bundle to start up unicorn. rbenv is single user, only 'joe' has bundle installed. The path to bundle is likely stored in my .bashrc file. However .bashrc file which is not invoked by login in through su - and that caused the bundle not installed error.
I included the paths related to rbenv in .profile. This way when root su - into 'joe' the paths are loaded.
回答2:
On Unbutu I created I file /etc/profile.d/rbenv.sh with this content:
export RBENV_ROOT=/home/YOUR_USER_PATH/.rbenv
export PATH=$RBENV_ROOT/shims:$RBENV_ROOT/bin:$PATH
来源:https://stackoverflow.com/questions/31971806/unicorn-service-upstart-script-throws-su-bundle-command-not-found