Unicorn service upstart script throws “-su: bundle: command not found”

眉间皱痕 提交于 2020-01-01 14:36:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!