unicorn using old release executable (rbenv + runit) - bundler

I am running into an issue that should be easy to fix but I can't seem to find the magic.
Unicorn is using runit and attempting to point to the current releases Gemfile. At the end of each deploy, unicorn is sent a USR2 signal and the old master is successfully replaced using the "zero downtime deploy" method. This was all fine for a while, until I hit the point where old releases were being cleaned out. It was then I realized runit was pointing to the release directory that was used when the unicorn master was first created.
I have tried adding this block to unicorn.rb:
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "/home/deploy/app/current/Gemfile"
end
I have also tried wrapping bundler with this script:
#!/bin/bash
source /etc/profile.d/rbenv.sh
bundle $#
I have even tried setting the BUNDLE_GEMFILE env variable manually, but none of these seem to work.
When I take a look at the unicorn stdout after deploying I see this:
executing ["/home/deploy/app/releases/1279f2e2d88c90ba4e02eaba611a4ee6de6fee77/vendor/bundle/ruby/2.0.0/bin/unicorn", "-E", "staging", "-c", "/home/deploy/app/shared/config/unicorn.rb", "-D", {12=>#<Kgio::UNIXServer:fd 12>}] (in /home/deploy/app/releases/d6a582935d84cc0bec2e760c14d804a7c5e2146c)
As you can see, the command is being run in the new release directory (d6a582935d84cc0bec2e760c14d804a7c5e2146c), but the unicron executable is pointing to an old release (1279f2e2d88c90ba4e02eaba611a4ee6de6fee77).
If I manually stop/start unicorn, then the correct release is used, but that would mean not having "zero downtime deploys".
I'm not sure what the issue is, but I figure it is something to do with rbenv paths. Anybody have suggestions for how to get unicorn pointing to the correct (current) release?
I am using the application_ruby LWRP with Chef to deploy if anyone is familiar. It basically just emulates Capistrano.
Relevant configs:
unicorn.rb:
current_path = '/home/deploy/app/current'
working_directory '/home/deploy/app/current'
worker_processes 8
listen "/home/deploy/app/shared/sockets/cms.sock"
timeout 60
pid '/home/deploy/app/shared/pids/unicorn.pid'
stderr_path '/home/deploy/app/shared/log/unicorn/unicorn.stderr.log'
stdout_path '/home/deploy/app/shared/log/unicorn/unicorn.stderr.log'
preload_app true
# Enable Copy on Write Garbage Collector - http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
end
before_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
end
old_pid = "/home/deploy/app/shared/pids/unicorn.pid.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :TERM : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
# sleep 0 for small app, sleep 2 for big (300mb+)
sleep 1
end
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "#{current_path}/Gemfile"
end
after_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
end
runit unicorn script:
#!/bin/bash
if [ -d "/home/deploy/app/current" ] ; then
function is_unicorn_alive {
set +e
if [ -n $1 ] && kill -0 $1 >/dev/null 2>&1; then
echo "yes"
fi
set -e
}
echo "Service PID: $$"
CUR_PID_FILE="/home/deploy/app/shared/pids/unicorn.pid"
OLD_PID_FILE=$CUR_PID_FILE.oldbin
if [ -e $OLD_PID_FILE ]; then
OLD_PID=$(cat $OLD_PID_FILE)
echo "Waiting for existing master ($OLD_PID) to exit"
while [ -n "$(is_unicorn_alive $OLD_PID)" ]; do
/bin/echo -n '.'
sleep 2
done
fi
if [ -e $CUR_PID_FILE ]; then
CUR_PID=$(cat $CUR_PID_FILE)
if [ -n "$(is_unicorn_alive $CUR_PID)" ]; then
echo "Unicorn master already running. PID: $CUR_PID"
RUNNING=true
fi
fi
if [ ! $RUNNING ]; then
echo "Starting unicorn"
cd /home/deploy/app/current
chown deploy:deploy /home/deploy/app/shared/pids/
chpst -u deploy \
/opt/rbenv/shims/bundle exec \
unicorn \
-E staging -c /home/deploy/app/shared/config/unicorn.rb -D
sleep 3
CUR_PID=$(cat $CUR_PID_FILE)
fi
function restart {
echo "Initialize new master with USR2"
kill -USR2 $CUR_PID
# Make runit restart to pick up new unicorn pid
sleep 2
echo "Restarting service to capture new pid"
exit
}
function graceful_shutdown {
echo "Initializing graceful shutdown"
kill -QUIT $CUR_PID
}
function unicorn_interrupted {
echo "Unicorn process interrupted. Possibly a runit thing?"
}
trap restart HUP QUIT USR2 INT
trap graceful_shutdown TERM KILL
trap unicorn_interrupted ALRM
echo "Waiting for current master to die. PID: ($CUR_PID)"
while [ -n "$(is_unicorn_alive $CUR_PID)" ]; do
/bin/echo -n '.'
sleep 2
done
else
sleep 1
fi

Found it!
Added this to unicorn.rb:
Unicorn::HttpServer::START_CTX[0] = "#{current_path}/bin/unicorn"

Related

restarting delayed_job script via monit breaks /usr/lib/ruby/2.3.0/rubygems/core_ext/kern

So i am trying to use monit to monitor my delayed_job processes. And to do that, i have written this
/home/deploy/sites/app.project.com.my/shared/delayed_job.monitrc
check process delayed_job_0
with pidfile /home/deploy/sites/app.project.com.my/shared/pids/delayed_job.0.pid
start program = "/home/deploy/sites/app.project.com.my/shared/delayed_job.sh start staging 0"
as uid deploy and gid deploy
stop program = "/bin/su - deploy -c '/home/deploy/sites/app.project.com.my/current/bin/delayed_job stop staging 0'"
group delayed_job
I have also written this script
/home/deploy/sites/app.project.com.my/shared/delayed_job.sh
#!/bin/bash
APP_NAME=app.project.com.my
APP_DIR=/home/deploy/sites
RAILS_ROOT=$APP_DIR/$APP_NAME/current
LOG_FILE=$APP_DIR/$APP_NAME/shared/delayed_job_monit.log
exec 2>&1
if [ "$3" ]; then
RUNNER="$3"
else
RUNNER=0
fi
echo "Runner: $RUNNER"
ENVIRONMENT=$2
echo "Env: $ENVIRONMENT"
PID_FILE=$RAILS_ROOT/tmp/pids/delayed_job.$RUNNER.pid
echo "Pid: $PID_FILE"
cd $RAILS_ROOT
echo "Received $1"
function stop {
cd $RAILS_ROOT
RAILS_ENV=$ENVIRONMENT /usr/bin/env bin/delayed_job stop -i $RUNNER
}
function start {
if [ -f $PID_FILE ]; then
echo "Pid Found. Deleting PID FILE: $PID_FILE"
rm -f $PID_FILE
fi
CMD=" /usr/bin/env RAILS_ENV=$ENVIRONMENT bin/delayed_job start -i $RUNNER"
cd $RAILS_ROOT
exec $CMD
}
case $1 in
start)
stop
start
;;
stop)
stop
;;
*)
echo "WTF"
;;
esac
Now when in this folder /home/deploy/sites/app.project.com.my/shared/, if i run the delayed_job.sh script like this ./delayed_job start staging 0. it works properly and the delayed_job is restarted.
But when i run the monit script sudo monit start delayed_job_0, i get an error /usr/lib/ruby/2.3.0/rubygems/core_ext/kern
Currently not sure how to get rid of this error.

Bash script to start spring-boot app and finish script

I have a bash script to deploy my spring-boot app (using bamboo).
script gets hung on this as the spring-boot app launches and is running
java -jar myApp.jar
I tried running it in the background with
java -jar myApp.jar &
as well as
java -jar myApp.jar &
disown
just "&" seems to do nothing while the "&" followed by "disown" made the script fail.
How do I let the script finish while the spring-boot app keeps running?
There is multiple options, one as mentioned is 'nohup' command. Another way to run is using 'screen' virtual terminal. But I would suggest you take a considerably better approach and run it as any other background service on *nix machines (like apache, mysql, etc.)
Here my very simple code that I have inside of /etc/init.d/great-spring-boot-app script, you can edit few lines to suite your conventions and save this file with
any name inside of /etc/init.d/ directory, for example /etc/init.d/my-cool-spring-boot-app
Then make it executable:
chmod +x /etc/init.d/my-cool-spring-boot-app
Afterwards can simply start process by doing something like
sudo service my-cool-spring-boot-app start
Other options are:
stop|restart|status
#!/bin/bash -
#=-= START OF CUSTOM SERVICE CONFIGURATION =-#
# Where micro service war/jar file sits?
MS_HOME=/opt/MY_MICRO_SERVICE_ROOT_DIRECTORY # <--- EDIT THIS LINE
# Actual file name of Micro Service (jar or war),
# ms-service.war or something-0.0.1-SNAPSHOT.jar, etc.
MS_JAR=MY_SPRING_BOOT_APPLICATION-0.0.1-SNAPSHOT.war # <--- EDIT THIS LINE
# ^^^ that should relative to MS_HOME directory.
# Which username we should run as.
RUNASUSER=USER_TO_RUN_AS; # <-- EDIT THIS LINE,
# if port number for spring boot is < 1024 it needs root perm.
JAVA_HOME=/usr/local/jdk1.8.0_60; # <-- EDIT THIS, Where is your JDK/JRE?
PATH=${JAVA_HOME}/bin:${PATH};
SHUTDOWN_WAIT=20; # before issuing kill -9 on process.
export PATH JAVA_HOME
# These options are used when micro service is starting
# Add whatever you want/need here... overrides application*.yml.
OPTIONS="
-Dserver.port=8080
-Dspring.profiles.active=dev
";
#=-= END OF CUSTOM CONFIGURATION =-=#
# Try to get PID of spring jar/war
MS_PID=`ps fax|grep java|grep "${MS_JAR}"|awk '{print $1}'`
export MS_PID;
# Function: run_as
run_as() {
local iam iwant;
iam=$(id -nu);
iwant="$1";
shift;
if [ "${iam}" = "${iwant}" ]; then {
eval $*;
}
else {
/bin/su -p -s /bin/sh ${iwant} $*;
} fi;
}
# Function: start
start() {
pid=${MS_PID}
if [ -n "${pid}" ]; then {
echo "Micro service is already running (pid: ${pid})";
}
else {
# Start screener ms
echo "Starting micro service";
cd $MS_HOME
run_as ${RUNASUSER} java -jar ${OPTIONS} ./${MS_JAR};
# java -jar ${OPTIONS} ./${MS_JAR}
} fi;
# return 0;
}
# Function: stop
stop() {
pid=${MS_PID}
if [ -n "${pid}" ]; then {
run_as ${RUNASUSER} kill -TERM $pid
echo -ne "Stopping micro service module";
kwait=${SHUTDOWN_WAIT};
count=0;
while kill -0 ${pid} 2>/dev/null && [ ${count} -le ${kwait} ]; do {
printf ".";
sleep 1;
(( count++ ));
} done;
echo;
if [ ${count} -gt ${kwait} ]; then {
printf "process is still running after %d seconds, killing process" \
${SHUTDOWN_WAIT};
kill ${pid};
sleep 3;
# if it's still running use kill -9
#
if kill -0 ${pid} 2>/dev/null; then {
echo "process is still running, using kill -9";
kill -9 ${pid}
sleep 3;
} fi;
} fi;
if kill -0 ${pid} 2>/dev/null; then {
echo "process is still running, I give up";
}
else {
# success, delete PID file, if you have used it with spring boot
# rm -f ${SPRING_BOOT_APP_PID};
} fi;
}
else {
echo "Micro service is not running";
} fi;
#return 0;
}
# Main Code
case $1 in
start)
start;
;;
stop)
stop;
;;
restart)
stop;
sleep 1;
start;
;;
status)
pid=$MS_PID
if [ "${pid}" ]; then {
echo "Micro service module is running with pid: ${pid}";
}
else {
echo "Micro service module is not running";
} fi;
;;
esac
exit 0;
This is the appropriate way to start background service(s) on Linux.
nohup java -jar myApp.jar &
nohup will intercept the HUP (hangup) signal when the TTY closes. This prevents the process from being terminated when the user logs out / your remote session ends. The ampersand is for starting the process in the background.
Easy stop / start spring boot application uber jar
https://github.com/tyrion9/spring-boot-startup-script
Copy uber jar file in the same folder
./bootstrap.sh start
./bootstrap.sh stop
./bootstrap.sh restart
Using start and shutdown scripts
I have answered similar question here.
You could use a set of scripts to achieve this. For example a startup.sh may look like this. It will start the application and write the process id to /path/to/app/pid.file .And the nohup disowns the process so the process doesn't hold on to current TTY session.
#!/bin/bash
nohup java -jar /path/to/app/hello-world.jar > /path/to/log.txt 2>&1 &
echo $! > /path/to/app/pid.file
And a shutdown.sh may look like this.
#!/bin/bash
kill $(cat /path/to/app/pid.file)
You can find more detail in my post. https://springhow.com/start-stop-scripts-for-spring-boot-applications/

Change max-job size of beanstalkd

Does somebody how to change the max-job size of beanstalkd ?
I have the problem that I get the message JOB_TOO_BIG and at Adding Job to beanstalkd, it says that the default size is 65k.
Does somebody know how to change that ?
EDIT:
my beanstalkd init-script in the folder /etc/init.d looks like the following (I added the -z option to increase the job size):
#!/bin/sh
#
# Copyright (c) 2007 Javier Fernandez-Sanguino <jfs#debian.org>
#
# This is free software; you may redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2,
# or (at your option) any later version.
#
# This is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License with
# the Debian operating system, in /usr/share/common-licenses/GPL; if
# not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307 USA
#
### BEGIN INIT INFO
# Provides: beanstalkd
# Required-Start: $remote_fs $network $local_fs
# Required-Stop: $remote_fs $network $local_fs
# Should-Start: $named
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: in-memory workqueue service
# Description: beanstalk is a simple, fast, queueing server. Its
# interface is generic, but was originally designed
# for reducing the latency of page views in high-volume
# web applications by running time-consuming tasks
# asynchronously.
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/beanstalkd # Introduce the server's location here
NAME=beanstalkd # Introduce the short server's name here
DESC="in-memory queueing server" # Introduce a short description here
LOGDIR=/var/log/beanstalkd # Log directory to use
BEANSTALKD_LISTEN_ADDR=0.0.0.0
BEANSTALKD_LISTEN_PORT=11300
PIDFILE=/var/run/$NAME.pid
test -x $DAEMON || exit 0
. /lib/lsb/init-functions
# Default options, these can be overriden by the information
# at /etc/default/$NAME
DAEMON_OPTS="-l $BEANSTALKD_LISTEN_ADDR -p $BEANSTALKD_LISTEN_PORT -z 550000000000" # Additional options given to the server
#DIETIME=10 # Time to wait for the server to die, in seconds
# If this value is set too low you might not
# let some servers to die gracefully and
# 'restart' will not work
STARTTIME=1 # Time to wait for the server to start, in seconds
# If this value is set each time the server is
# started (on start or restart) the script will
# stall to try to determine if it is running
# If it is not set and the server takes time
# to setup a pid file the log message might
# be a false positive (says it did not start
# when it actually did)
#LOGFILE=$LOGDIR/$NAME.log # Server logfile
DAEMONUSER=root #beanstalkd # Users to run the daemons as. If this value
# is set start-stop-daemon will chuid the server
# Include defaults if available
if [ -f /etc/default/$NAME ] ; then
. /etc/default/$NAME
fi
# Check that the user exists (if we set a user)
# Does the user exist?
if [ -n "$DAEMONUSER" ] ; then
if getent passwd | grep -q "^$DAEMONUSER:"; then
# Obtain the uid and gid
DAEMONUID=`getent passwd |grep "^$DAEMONUSER:" | awk -F : '{print $3}'`
DAEMONGID=`getent passwd |grep "^$DAEMONUSER:" | awk -F : '{print $4}'`
else
log_failure_msg "The user $DAEMONUSER, required to run $NAME does not exist."
exit 0
fi
fi
set -e
running_pid() {
# Check if a given process pid's cmdline matches a given name
pid=$1
name=$2
[ -z "$pid" ] && return 1
[ ! -d /proc/$pid ] && return 1
cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
# Is this the expected server
[ "$cmd" != "$name" ] && return 1
return 0
}
running() {
# Check if the process is running looking at /proc
# (works for all users)
# No pidfile, probably no daemon present
[ ! -f "$PIDFILE" ] && return 1
pid=`cat $PIDFILE`
running_pid $pid $DAEMON || return 1
return 0
}
start_server() {
# Start the process using the wrapper
if [ "x$START" != "xyes" -a "x$START" != "xtrue" ]; then
echo ""
echo "beanstalkd not configured to start, please edit /etc/default/beanstalkd to enable"
exit 0
fi
if [ -z "$DAEMONUSER" ] ; then
start_daemon -p $PIDFILE $DAEMON $DAEMON_OPTS
errcode=$?
else
# if we are using a daemonuser then change the user id
start-stop-daemon --start --quiet --pidfile $PIDFILE \
--chuid $DAEMONUSER --make-pidfile --oknodo \
--background --exec $DAEMON -- $DAEMON_OPTS
errcode=$?
fi
return $errcode
}
stop_server() {
# Stop the process using the wrapper
if [ -z "$DAEMONUSER" ] ; then
killproc -p $PIDFILE $DAEMON
errcode=$?
else
# if we are using a daemonuser then look for process that match
start-stop-daemon --stop --quiet --pidfile $PIDFILE \
--user $DAEMONUSER \
--exec $DAEMON
errcode=$?
fi
rm -f $PIDFILE
return $errcode
}
reload_server() {
[ ! -f "$PIDFILE" ] && return 1
pid=pidofproc $PIDFILE # This is the daemon's pid
# Send a SIGHUP
kill -1 $pid
return $?
}
force_stop() {
# Force the process to die killing it manually
[ ! -e "$PIDFILE" ] && return
if running ; then
kill -15 $pid
# Is it really dead?
sleep "$DIETIME"s
if running ; then
kill -9 $pid
sleep "$DIETIME"s
if running ; then
echo "Cannot kill $NAME (pid=$pid)!"
exit 0
fi
fi
fi
rm -f $PIDFILE
}
case "$1" in
start)
log_daemon_msg "Starting $DESC " "$NAME"
# Check if it's running first
if running ; then
log_progress_msg "apparently already running"
log_end_msg 0
exit 0
fi
if start_server ; then
# NOTE: Some servers might die some time after they start,
# this code will detect this issue if STARTTIME is set
# to a reasonable value
[ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time
if running ; then
# It's ok, the server started and is running
log_end_msg 0
else
# It is not running after we did start
log_end_msg 1
fi
else
# Either we could not start it
log_end_msg 1
fi
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
if running ; then
# Only stop the server if we see it running
errcode=0
stop_server || errcode=$?
log_end_msg $errcode
else
# If it's not running don't do anything
log_progress_msg "apparently not running"
log_end_msg 0
exit 0
fi
;;
force-stop)
# First try to stop gracefully the program
$0 stop
if running; then
# If it's still running try to kill it more forcefully
log_daemon_msg "Stopping (force) $DESC" "$NAME"
errcode=0
force_stop || errcode=$?
log_end_msg $errcode
fi
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
errcode=0
stop_server || errcode=$?
# Wait some sensible amount, some server need this
[ -n "$DIETIME" ] && sleep $DIETIME
start_server || errcode=$?
[ -n "$STARTTIME" ] && sleep $STARTTIME
running || errcode=$?
log_end_msg $errcode
;;
status)
log_daemon_msg "Checking status of $DESC" "$NAME"
if running ; then
log_progress_msg "running"
log_end_msg 0
else
log_progress_msg "apparently not running ... "
log_end_msg 1
exit 0
fi
;;
reload)
log_warning_msg "Reloading $NAME daemon: not implemented (use restart)."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0
And my beanstalkd.conf file which is in the folder /etc/default looks like the following:
## Defaults for the beanstalkd init script, /etc/init.d/beanstalkd on
## Debian systems. Append "-b /var/lib/beanstalkd" for persistent
## storage.
BEANSTALKD_LISTEN_ADDR=0.0.0.0
BEANSTALKD_LISTEN_PORT=11300
# create the journal path before use !!!
BEANSTALKD_JOURNAL_PATH="/var/lib/beanstalkd"
DAEMON_OPTS="-l $BEANSTALKD_LISTEN_ADDR -p $BEANSTALKD_LISTEN_PORT -z 550000000000 -b $BEANSTALKD_JOURNAL_PATH -V"
## Uncomment to enable startup during boot.
START=yes
best regards,
The answer by slickorange in the following link might help you:
JOB_TOO_BIG Pheanstalk - what can be done?
The size of beanstalkd job can be increased by adding the following line (or uncomment the existing BEANSTALKD_EXTRA line and edit it):
BEANSTALKD_EXTRA="-z 524280"
The size is specified in bytes, default size being 65535 bytes.
Restart beanstalkd after making the change:
sudo service beanstalkd restart
On Debian 8.7 x64 editing the settings in /etc/default/beanstalkd works. A bug probably.
I have systemctl in Debian 8 and my config looks slightly different from what is suggested here in other answers to increase the limit. This is what I did:
Edit the beanstalkd file in:
nano /etc/sysconfig/beanstalkd
Then increase the limit for MAX_JOB_SIZE from default 65535 to 524280
MAX_JOB_SIZE=-z 524280
Restart beanstalkd and check the status:
service beanstalkd restart
systemctl status beanstalkd
There are settings for the daemon
-b DIR wal directory
-f MS fsync at most once every MS milliseconds (use -f0 for "always fsync")
-F never fsync (default)
-l ADDR listen on address (default is 0.0.0.0)
-p PORT listen on port (default is 11300)
-u USER become user and group
-z BYTES set the maximum job size in bytes (default is 65535)
-s BYTES set the size of each wal file (default is 10485760)
(will be rounded up to a multiple of 512 bytes)
-c compact the binlog (default)
-n do not compact the binlog
-v show version information
-V increase verbosity
-h show this help
So based on your Linux, you should find out where this is kept and change it. Usually it's under beanstalkd.conf

Loading God scripts on startup - requires global gems?

I use God to watch over my Ruby APIs and services. I have created Init scripts to start up these services when the server boots. Doing this has led me to a couple of questions.
Firstly I have to have the scripts running as root? I found that as it loads with init.d scripts that the processes will then be managed by root - requiring Sudo for any changes.
Secondly, I have created RVM wrappers for some of the main processes (such as thin) which work brilliantly. But have found that some of the gems I use such as the Mongo gem will not get loaded from the context of the bundler (I assume that this is due to how the script is loaded and that it is loaded as root?) So I am forced to do a Gem install Mongo (and bson)
Is there a way to get init.d loaded scripts to load in the context of the bundler?
I might be doing this completely wrong as I am still fairly new to Ruby deployment and Linux configurations.
Here is an example of my god script:
require 'yaml'
config_path = '/opt/broker/current/config/api_config.yml'
config = YAML.load_file config_path
God.watch do |w|
w.name = 'Broker_API'
pid_file = config[:pid_file_path]
w.pid_file = pid_file
w.behavior :clean_pid_file
w.dir = config[:deployed_current_path]
w.env = config[:deployed_current_path]
port = config[:api_port]
server_logs = config[:api_logs]
config_ru = config[:api_config_file]
w.start = 'bundle exec thin -l %s -P %s -d -D -R %s -p %s --threaded start' %[server_logs, pid_file, config_ru, port]
w.stop = 'bundle exec thin -l %s -P %s -d -D -R %s -p %s --threaded stop' %[server_logs, pid_file, config_ru, port]
w.restart = 'bundle exec thin -l %s -P %s -d -D -R %s -p %s --threaded restart' %[server_logs, pid_file, config_ru, port]
w.log = config[:api_god_log]
w.keepalive
end
and my init script:
#!/bin/sh
### BEGIN INIT INFO
# Provides: god
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: God
### END INIT INFO
NAME=god
DESC=god
GOD_BIN=/home/username/.rvm/wrappers/Godrunner/god
GOD_CONFIG=/etc/god/god.conf
GOD_LOG=/var/log/god.log
GOD_PID=/var/run/god.pid
set -e
RETVAL=0
case "$1" in
start)
echo -n "Starting $DESC: "
$GOD_BIN load -c $GOD_CONFIG
exit 0
fi
RETVAL=0
case "$1" in
start)
echo -n "Starting $DESC: "
$GOD_BIN load -c $GOD_CONFIG
RETVAL=$?
echo "$NAME."
;;
status)
$GOD_BIN status
RETVAL=$?
;;
*)
echo "Usage: god {start|status}"
exit 1
;;
esac
exit $RETVAL
I have solved it this way:
daemon --user $USER "$GOD_BIN \
-c $CONFIG_FILE \
-l $LOG_FILE \
--log-level $LOG_LEVEL \
-P $PID_FILE >/dev/null"
This is the part which should replace your $GOD_BIN load -c $GOD_CONFIG. And now God runs as $USER.
Now if you want it to know where your ruby and gems are you will have to provide it with this information. I am doing
source /etc/profile.d/ruby.sh
somewhere in the beginning of the script.
ruby.sh contents:
export PATH=/opt/ruby-2.1/bin/:$PATH
export GEM_PATH=/opt/ruby-2.1/lib64/ruby/gems/2.1.0

Launch Java application at startup on Centos

I need to launch a Java application on Centos (5.9) startup.
I am trying to start a simple script (named "lanzar.sh") on Centos at boot time:
#!/bin/sh
cd /home/someuser/Desktop/Dist
java -jar SomeApp.jar
I append the line "/bin/sh /home/someuser/Desktop/Dist/lanzar.sh" to /etc/rc.d/rc.local. But the java application does not start. I have:
Granted 755 rights to the /etc/rc.d/rc.local file
Write the content of the "lanzar.sh" into /etc/rc.d/rc.local. Separated with semicolon, and in different lines.
Changing "lanzar.sh" of location.
Other things, taken from other threads that did not work for me.
My rc.loca looks like:
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
#
#Some comment
#Some comment
#Some comment
touch /var/lock/subsys/local
/bin/sh /home/fernando/Desktop/Dist/lanzar.sh
Note: I know similar questions have been asked before, but after testing many of the answers that I have found by googling with no success, I had to ask this myself.
I highly recommend that you explore the /etc/init.d directory of your server and the /etc/rc3.d directory. See how the names of the files in /etc/rc3.d are symbolically linked to the names in the /etc/init.d directory. Notice how the files in /etc/rc3.d all start with Sxx or Kxxwherexx is a number between 00 to 99.
What I am about to tell you is officially all wrong. These startup scripts are way more complicated today that what I describe, but it's a basic outline of what's going on.
In standard Unix and Linux, startup scripts were normally stored in /etc/init.d and then linked to the /etc/rcX.d directory where X stood for what was called the Init States of the server. (Yes, I'm linking to an SCO Unix page, but they were all pretty similar).
Note that Init State 3 is running in multi-user mode and that all the daemons are started. This is why I am telling you to look in /etc/rc3.d.
When the server enters that init state, it runs all of the script starting with S in alphabetical order. It runs each script with the parameter start after it. So, S01xxxx starts before S03xxx which starts before S99xxxxx.
When the server exits that init state, it runs all of the scripts that start with K in alphabetical order, and passes the stop parameter to them.
Now, Centos, Redhat, and Fedora setup handles a lot of this for you. You specify which service you depend upon, and it figures out startup and shutdown order. However, nothing is preventing you from munging a startup script and creating your own links.
By the way, speaking about Java programs that startup and shutdown... Jenkins is a Java program that's started in a very similar way as your program. Here's the /etc/init.d script I got off of Jenkins website:
#!/bin/bash
#
# Startup script for Jenkins
#
# chkconfig: - 84 16
# description: Jenkins CI server
# Source function library.
. /etc/rc.d/init.d/functions
[ -z "$JAVA_HOME" -a -x /etc/profile.d/java.sh ] && . /etc/profile.d/java.sh
JENKINS_HOME=/var/jenkins
WAR="$JENKINS_HOME/jenkins.war"
LOG="/var/log/jenkins.log"
LOCK="/var/lock/subsys/jenkins"
export JENKINS_HOME
RETVAL=0
pid_of_jenkins() {
pgrep -f "java.*jenkins"
}
start() {
[ -e "$LOG" ] && cnt=`wc -l "$LOG" | awk '{ print $1 }'` || cnt=1
echo -n $"Starting jenkins: "
cd "$JENKINS_HOME"
nohup java -jar "$WAR" --httpPort=-1 --ajp13Port=8010 --prefix=/jenkins >> "$LOG" 2>&1 &
while { pid_of_jenkins > /dev/null ; } &&
! { tail +$cnt "$LOG" | grep -q 'Winstone Servlet Engine .* running' ; } ; do
sleep 1
done
pid_of_jenkins > /dev/null
RETVAL=$?
[ $RETVAL = 0 ] && success $"$STRING" || failure $"$STRING"
echo
[ $RETVAL = 0 ] && touch "$LOCK"
}
stop() {
echo -n "Stopping jenkins: "
pid=`pid_of_jenkins`
[ -n "$pid" ] && kill $pid
RETVAL=$?
cnt=10
while [ $RETVAL = 0 -a $cnt -gt 0 ] &&
{ pid_of_jenkins > /dev/null ; } ; do
sleep 1
((cnt--))
done
[ $RETVAL = 0 ] && rm -f "$LOCK"
[ $RETVAL = 0 ] && success $"$STRING" || failure $"$STRING"
echo
}
status() {
pid=`pid_of_jenkins`
if [ -n "$pid" ]; then
echo "jenkins (pid $pid) is running..."
return 0
fi
if [ -f "$LOCK" ]; then
echo $"${base} dead but subsys locked"
return 2
fi
echo "jenkins is stopped"
return 3
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit $RETVAL
It'll give you something to work with.

Resources