Unicorn is a very fast app server for Ruby on Rails. You just have to go to the APP_ROOT and type in “unicorn_rails”. And your app is running.
The problem with that is, if your server reboots your app is down. And you have to start it again by hand. That is not so cool!
Wouldn’t it be cool if you could start your Ruby on Rails like that:
/etc/init.d/unicorn start
and stop it like that:
/etc/init.d/unicorn stop
like all other services on Linux? And after a reboot unicorn starts automatically.
That is possible. Just use this script here for starting and stopping unicorn.
#!/bin/bash ### BEGIN INIT INFO # Provides: unicorn # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" BUNDLE=/usr/local/bin/bundle UNICORN=/usr/local/bin/unicorn_rails KILL=/bin/kill APP_ROOT=/var/www/my_app/current PID=$APP_ROOT/pids/unicorn.pid OLD_PID=$APP_ROOT/pids/unicorn.pid.oldbin CONF=$APP_ROOT/unicorn.conf.rb GEM_HOME=/var/www/my_app/shared/bundle/ruby/2.1.0/gems/ sig () { test -s "$PID" && kill -$1 `cat $PID` } case "$1" in start) echo "Starting unicorn rails app ..." cd $APP_ROOT if [ $USER == "ubuntu" ] then $BUNDLE exec unicorn_rails -D -c $CONF else su ubuntu -c "$BUNDLE exec unicorn_rails -D -c $CONF" fi echo "Unicorn rails app started!" ;; stop) echo "Stoping unicorn rails app ..." sig QUIT && exit 0 echo "Not running" ;; restart) if [ -f $PID ]; then echo "Unicorn PID $PID exists" /bin/kill -s USR2 `/bin/cat $PID` sleep 30 echo "Old PID $OLD_PID" /bin/kill -9 `/bin/cat $OLD_PID` else echo "Unicorn rails app is not running. Lets start it up!" $0 start fi ;; status) ;; *) echo "Usage: $0 {start|stop|restart|status}" ;; esac
Just customize the paths to your server and place the script in “/etc/init.d”. And ensure that the script is executable.
chmod ugo+x <YOUR_SCRIPT>
Than navigate to the direcotry “/etc/init.d” and execute this here:
update-rc.d <YOUR_SCRIPT> defaults
That will add your script to the default runlevels. So that your script will be executed by every reboot.
not really good way to run unicorn as root..
it’s a huge huge security risk..
here is what I’m using for starting redmine:
#!/bin/bash
### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
UNICORN=/var/lib/gems/1.8/bin/unicorn_rails
KILL=/bin/kill
APP_ROOT=/var/www/redmine
PID=$APP_ROOT/tmp/pids/unicorn.pid
CONFIG=$APP_ROOT/config/unicorn.rb
GEM_HOME=/var/lib/gems/1.8/gems/
RUNUSER=www-data
sig () {
test -s “$PID” && kill -$1 `cat $PID`
}
case “$1” in
start)
echo -ne “Starting unicorn…”
cd $APP_ROOT
su -c “${UNICORN} -E production -c ${CONFIG} -D” www-data
if [ “$?” != 0 ]; then
echo -ne “[FAILED]\n”
else
echo -ne “[OK]\n”
fi
;;
stop)
sig QUIT && exit 0
echo >&2 “Not running”
;;
restart)
$0 stop
$0 start
;;
status)
;;
*)
echo “Usage: $0 {start|stop|restart|status}”
;;
esac
Great site you have here.. It’s hard to find good quality writing like yours nowadays. I honestly appreciate people like you! Take care!
Reblogged this on My Corner of the Web and commented:
This article saved my life. Set up Unicorn to start on server reboot.
Happy to hear that 🙂
Hi, Im trying to implement your script, but its not working for me. I get:
Starting unicorn…
master failed to start, check stderr log for details
That can have multiple reasons. For example if you start the script as non-root user but some directories need root access. You can turn on the logging for unicorn in unicorn.conf.rb. You should have there this 2 lines:
stderr_path “/var/www/yourapp/shared/log/unicorn.stderr.log”
stdout_path “/var/www/yourapp/shared/log/unicorn.stdout.log”
That will give you more info on the error.
I just updated the script. It is more sophisticated now! The current version starts the unicorn daemon as non privileged user ubuntu. That’s more secure!
When I run the command without using su -c, it works just fine, but for some reason when I run it with that as my app’s user I get this:
/usr/bin/env: ruby_executable_hooks: No such file or directory
Any ideas?
It seems that the ubuntu user doesn’t has setup his ruby paths correctly. Login as ubuntu and execute the same command as ubuntu. Does it work?
Instead of ubuntu I am using a user with access to the directory and paths setup correctly. When I login as this user and run the command it works fine, but for some reason when I use su it doesn’t, which seems very strange. When I ran su ubuntu I get this:
No passwd entry for user ‘ubuntu’
I ran this to check if there was an ubuntu user:
cut -d: -f1 /etc/passwd
and saw no entry for the user ubuntu
I also debugged a little and found that running this will make it have the same error message:
su myuser -c “$BUNDLE”
It seems that some paths are not set correctly. Try to set ruby_executable_hooks explicitly in the unicorn.sh script. That should solve the issue.
Ho i can change user root to other user who can start this comand
run comand source ~/.rvm/scripts/rvm
then go to cd /home/bp/bp/current
and run command bundle exec unicorn -c /home/bp/bp/current/config/unicorn/production.rb -E deployment -D
Regards
GRzegorz