Ruby on rails with unicorn not readable file - ruby-on-rails

I'm trying to build in ruby on rails environment but when I check the unicorn status it gives me the following error and I don't know what to do. I checked the path to the config.rb and it's there.
/usr/local/rvm/gems/ruby-2.2.2/gems/unicorn-5.1.0/lib/unicorn/configurator.rb:644:in `parse_rackup_file': rackup file (status) not readable (ArgumentError)
from /usr/local/rvm/gems/ruby-2.2.2/gems/unicorn-5.1.0/lib/unicorn/configurator.rb:74:in `reload'
from /usr/local/rvm/gems/ruby-2.2.2/gems/unicorn-5.1.0/lib/unicorn/configurator.rb:65:in `initialize'
from /usr/local/rvm/gems/ruby-2.2.2/gems/unicorn-5.1.0/lib/unicorn/http_server.rb:76:in `new'
from /usr/local/rvm/gems/ruby-2.2.2/gems/unicorn-5.1.0/lib/unicorn/http_server.rb:76:in `initialize'
from /usr/local/rvm/gems/ruby-2.2.2/gems/unicorn-5.1.0/bin/unicorn:126:in `new'
from /usr/local/rvm/gems/ruby-2.2.2/gems/unicorn-5.1.0/bin/unicorn:126:in `<top (required)>'
from /usr/local/rvm/gems/ruby-2.2.2/bin/unicorn:23:in `load'
from /usr/local/rvm/gems/ruby-2.2.2/bin/unicorn:23:in `<main>'
from /usr/local/rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `eval'
from /usr/local/rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `<main>'
Unicorn config
#!/bin/bash
### 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: unicorn initscript
# Description: Unicorn is an HTTP server for Rack application
### END INIT INFO
# based on http://gist.github.com/308216 by http://github.com/mguterl
#
## A sample /etc/unicorn/my_app.conf
##
## RAILS_ENV=production
## RAILS_ROOT=/var/apps/www/my_app/current
## PID=$RAILS_ROOT/tmp/unicorn.pid
## START_CMD="bundle exec unicorn"
## USER="www-data"
#PATH=/usr/local/bin:/usr/bin:/bin
set -e
sig () {
test -s "$PID" && kill -$1 `cat "$PID"`
}
oldsig () {
test -s "$OLD_PID" && kill -$1 `cat "$OLD_PID"`
}
run_cmd() {
if [ -z "$SUDO" ]; then
$CMD
else
$SUDO "$CMD"
fi
}
cmd () {
case $1 in
start)
sig 0 && echo >&2 "Already running" && return
echo "Starting"
run_cmd
;;
stop)
sig QUIT && echo "Stopping" && return
echo >&2 "Not running"
;;
force-stop)
sig TERM && echo "Forcing a stop" && return
echo >&2 "Not running"
;;
restart|reload)
sig USR2 && sleep 5 && oldsig QUIT && echo "Killing old master" `cat $OLD_PID` && return
echo >&2 "Couldn't reload, starting '$CMD' instead"
run_cmd
;;
upgrade)
sig USR2 && echo Upgraded && return
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
run_cmd
;;
rotate)
sig USR1 && echo rotated logs OK && return
echo >&2 "Couldn't rotate logs" && return
;;
status)
sig 0 && echo >&2 "Already running" && return
echo >&2 "Not running" && return
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
return
;;
esac
}
setup () {
# echo -n "$RAILS_ROOT: "
cd $RAILS_ROOT || exit 1
"/usr/local/rvm/scripts/rvm"
#/usr/local/rvm/environments/ruby-1.9.2-p290#hacfest
if [ -z "$PID" ]; then
PID=$RAILS_ROOT/tmp/pids/unicorn.pid
fi
# if [ -z "$DATABASE_URL" ]; then
# DATABASE_URL=null
# fi
# export DATABASE_URL
export PID
export OLD_PID="$PID.oldbin"
export RAILS_ROOT
if [ -z "$START_CMD" ]; then
START_CMD="bundle exec unicorn"
fi
CMD="cd $RAILS_ROOT && $START_CMD -c $UNICORN_CONFIG -E $RAILS_ENV -D"
export CMD
echo "CMD: " $CMD
SUDO=""
# echo who: `whoami`
# echo user $USER
if [ "$USER" != `whoami` ]; then
SUDO="sudo -u $USER -s -H $RUNSHELL -c"
else
SUDO="$RUNSHELL -c"
fi
export SUDO
# echo "SUDO: "$SUDO
# echo $SHELL
}
start_stop () {
# either run the start/stop/reload/etc command for every config under /etc/unicorn
# or just do it for a specific one
# $1 contains the start/stop/etc command
# $2 if it exists, should be the specific config we want to act on
if [ -f "/etc/unicorn/$2.conf" ]; then
. /etc/unicorn/$2.conf
export UNICORN_CONFIG="/etc/unicorn/$2.unicorn.rb"
setup
cmd $1
else
for CONFIG in /etc/unicorn/*.conf; do
# import the variables
export UNICORN_CONFIG=`echo ${CONFIG} | sed 's/conf/unicorn.rb/'`
. $CONFIG
setup
# run the start/stop/etc command
cmd $1
unset PID
done
fi
}
ARGS="$1 $2"
start_stop $ARGS

Make sure that you run unicorn via command:
bundle exec unicorn -D -E <environment> -c config/unicorn.rb
And if it doesn't work, please share your file config/unicorn.rb

File being present at path does not mean it is readable by particular user.
Check that user that you're running unicorn under has access to the files and directories. Usually code owner and unicorn user are the same, so chown -R that_username:that_username /path/to/app/source accordingly.

Related

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!
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

Unicorn Rails looking for separate file/directory for each command?

I'm trying to deploy with Ruby 2.2.2, Rails 4, Capistrano 3, Unicorn and Nginx. When I run cap production deploy I get an error sating that Unicon can't find or access a directory for the "restart" command, stemming (I believe) from this line in my deploy.rb:
execute "/etc/init.d/unicorn_#{fetch(:application)}/unicorn_init.sh/#{command}"
The error:
SSHKit::Runner::ExecuteError: Exception while executing as deploy#0.0.0.0: /etc/init.d/unicorn_app/restart exit status: 126
/etc/init.d/unicorn_app/restart stdout: Nothing written
/etc/init.d/unicorn_app/restart stderr: /usr/bin/env: /etc/init.d/unicorn_app/restart: Permission denied
Deploy.rb
set :application, 'app'
set :repo_url, 'https://github.com/user/app.git'
set :deploy_to, '/opt/www/app'
set :user, 'deploy'
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets}
set :ssh_options, {
forward_agent: true,
port: 7822
}
namespace :deploy do
%w[start stop restart].each do |command|
desc 'Manage Unicorn'
task command do
on roles(:app), in: :sequence, wait: 1 do
execute "/etc/init.d/unicorn_#{fetch(:application)}/unicorn_init.sh/#{command}"
end
end
end
after :publishing, :restart
end
set :rvm_ruby_version, '2.2.2'
set :default_env, { rvm_bin_path: '/usr/local/rvm/bin' }
SSHKit.config.command_map[:rake] = "#{fetch(:default_env)[:rvm_bin_path]}/rvm ruby-#{fetch(:rvm_ruby_version)} do bundle exec rake"
Can anyone help me out here? I'll gladly post any missing info.
EDIT: unicorn_init.sh: I know 'testapp' is referenced in this file, but app is referenced elsewhere in this post. Please know that i'm consistent across all files with the name, I just changed them for the post.
#!/bin/sh
### 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: Manage unicorn server
# Description: Start, stop, restart unicorn server for a specific application.
### END INIT INFO
set -e
# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/opt/www/testapp/current
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT; bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
AS_USER=deploy
set -u
OLD_PIN="$PID.oldbin"
sig () {
test -s "$PID" && kill -$1 `cat $PID`
}
oldsig () {
test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
}
run () {
if [ "$(id -un)" = "$AS_USER" ]; then
eval $1
else
su -c "$1" - $AS_USER
fi
}
case "$1" in
start)
sig 0 && echo >&2 "Already running" && exit 0
run "$CMD"
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
run "$CMD"
;;
upgrade)
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
then
n=$TIMEOUT
while test -s $OLD_PIN && test $n -ge 0
do
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
echo
if test $n -lt 0 && test -s $OLD_PIN
then
echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
exit 1
fi
exit 0
fi
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
run "$CMD"
;;
reopen-logs)
sig USR1
;;
*)
echo >&2 "Usage: $0 "
exit 1
;;
esac

Syntax error near unexpected token `(' on service unicorn start on amazon EC2 linux

I am trying to setup Unicorn in Amazon EC2. I am following this blog.
But when I start Unicorn using:
sudo service unicorn_firstapp start
I am getting the following error:
/home/ec2-user/rails_projects/firstapp/config/unicorn.rb: line 2: syntax error near unexpected token `('
/home/ec2-user/rails_projects/firstapp/config/unicorn.rb: line 2: `app_dir = File.expand_path("../..", __FILE__)'
What is my mistake? If any one has any idea about this issue, please share it with me.
unicorn.rb:
# set path to application
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
working_directory app_dir
# Set unicorn options
worker_processes 2
preload_app true
timeout 30
# Set up socket location
listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64
# Logging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"
# Set master PID location
pid "#{shared_dir}/pids/unicorn.pid"
/etc/init.d/unicorn_firstapp:
#!/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="ec2-user"
APP_NAME="firstapp"
APP_ROOT="/home/$USER/rails_projects/$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"
#setting for RVM
RAILS_ENV=production
PID=$APP_ROOT/shared/pids/unicorn.pid
DESC="Unicorn app - $RAILS_ENV"
UNICORN="$APP_ROOT/config/unicorn.rb"
UNICORN_OPTS="-c $APP_ROOT/config/unicorn.rb -E $RAILS_ENV -D"
CMD="RAILS_ENV=$RAILS_ENV $UNICORN $UNICORN_OPTS"
TIMEOUT=60
# 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
Try including the correct hash-bang header, otherwise your code will be executed using your shell:
#!/usr/bin/env ruby
app_dir = File.expand_path("../..", __FILE__)
...
Hope that helps.

How to tell unicorn shell script in rails application to use specific ruby and gemset

How do I set up unicorn shell file to use ruby-2.1.2#my_gemset so that it can run as sudo service unicorn start. My Rails Application config folder contain unicorn.sh file which has the following content.
#!/bin/sh
### 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: Manage unicorn server
# Description: Start, stop, restart unicorn server for a specific application.
### END INIT INFO
set -e
# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-90}
APP_ROOT=/home/user/Documents/workspace/MyApp
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT;bundle exec bin/unicorn -c $APP_ROOT/config/unicorn.rb -E development"
AS_USER="www-data"
action="$1"
set -u
OLD_BIN="$PID.oldbin"
sig () {
test -s "$PID" && kill -$1 `cat $PID`
}
oldsig () {
test -s $OLD_BIN && kill -$1 `cat $OLD_BIN`
}
run () {
if [ "$(id -un)" = "$AS_USER" ]; then
eval $1
else
su -c "$1" - $AS_USER
fi
}
case "$1" in
start)
sig 0 && echo >&2 "Already running" && exit 0
run "$CMD"
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
run "$CMD"
;;
upgrade)
if sig USR2 && sleep 3
then
n=$TIMEOUT
while test -s $OLD_BIN && test $n -ge 0
do
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
echo
if test $n -lt 0 && test -s $OLD_BIN
then
echo >&2 "$OLD_BIN still exists after $TIMEOUT seconds"
exit 1
fi
exit 0
fi
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
run "$CMD"
;;
reopen-logs)
sig USR1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
exit 1
;;
esac
but when i run sudo service unicorn start I got this error
/var/lib/gems/1.8/gems/bundler-1.5.3/lib/bundler/runtime.rb:220: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040777
Could not find rake-10.4.2 in any of the sources
Run `bundle install` to install missing gems.
But actually i am using ruby-2.1.2#my_gemset. How do I tell shell script to use this gemset using rvm.
My bin/unicorn file has this content
#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'unicorn' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path('unicorn', 'unicorn')
I know i have to change the path of /usr/bin/env ruby to my ruby but don't know how to do this. Also please let me know how can I set up unicorn shell script to use specific gemset with specific ruby.Thanks
I'm using rvm in my remote server to manage my gems. I've committed the .ruby-gemset, and .ruby-version so that it's uniform. In my deployment script, I added the snippet below to make sure I'm running the command in the right folder with the correct set of gems. So execute:
source ~/.rvm/scripts/rvm; cd #{current_path}; /etc/init.d/unicorn #{command}"
I'm pretty sure this can be refactored further but I haven't gotten around to updating my script for a while. But so far, it's been working. I'm using Capistrano 3.
I haven't done this before but i think this will work -
Add this line -
CMD_TO_USE_GEMSET="cd $APP_ROOT; rvm use ruby-2.1.2#my_gemset"
after
CMD="cd $APP_ROOT;bundle exec bin/unicorn -c $APP_ROOT/config/unicorn.rb -E development"
in your unicorn.sh.
And write this in "start" and "restart|reload" section of your unicorn.sh after run "$CMD" -
run "$CMD_TO_USE_GEMSET"
and now run the command to restart unicorn -
sudo service unicorn start

Error with permission in Chef routine

I have the following Chef routine to generate a script to start/stop a unicorn daemon.
However I always get a Permission denied when Capistrano execute this file. What I'm doing wrong with its permissions?
# recipes/default.rb
template "/etc/init.d/unicorn_#{node['pod']['app_name']}" do
owner node['pod']['user']
group node['pod']['user']
mode 777
source "unicorn_init.erb"
variables( :app_name => node['pod']['app_name'], :user => node['pod']['user'] )
end
# templates/default/unicorn_init.rb
#!/bin/sh
set -e
# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/<%= #user %>/apps/<%= #app_name %>/current
PID=/var/run/unicorn/unicorn_<%= #app_name %>.pid
CMD="cd $APP_ROOT; bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
AS_USER=<%= #user %>
set -u
OLD_PIN="$PID.oldbin"
sig () {
test -s "$PID" && su -c "kill -$1 `cat $PID`" - $AS_USER
}
oldsig () {
test -s $OLD_PIN && sudo -c "kill -$1 `cat $OLD_PIN`" - $AS_USER
}
run () {
if [ "$(id -un)" = "$AS_USER" ]; then
eval $1
else
su -c "$1" - $AS_USER
fi
}
case "$1" in
start)
sig 0 && echo >&2 "Already running" && exit 0
run "$CMD"
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
run "$CMD"
;;
upgrade)
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
then
n=$TIMEOUT
while test -s $OLD_PIN && test $n -ge 0
do
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
echo
if test $n -lt 0 && test -s $OLD_PIN
then
echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
exit 1
fi
exit 0
fi
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
run "$CMD"
;;
reopen-logs)
sig USR1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
exit 1
;;
esac
As you can see, it doesn't set the correct mode for the file:
[2013-05-27T20:42:00+02:00] INFO: Processing template[/etc/init.d/unicorn_pod] action create (pod::default line 38)
[2013-05-27T20:42:00+02:00] INFO: template[/etc/init.d/unicorn_pod] owner changed to 1001
[2013-05-27T20:42:00+02:00] INFO: template[/etc/init.d/unicorn_pod] group changed to 110
[2013-05-27T20:42:00+02:00] INFO: template[/etc/init.d/unicorn_pod] mode changed to 1411
** [out :: localhost] -r----x--t 1 deployer deployer 1453 2013-05-27 17:48 unicorn_pod
See the docs. Mode should be octal or string:
template "/etc/init.d/unicorn_#{node['pod']['app_name']}" do
[...]
mode 0777 #or mode "777"
[...]
end

Resources