I'm fairly new to bash scripting, but it feel like I'm really missing something basic here. I'm trying to a barely modified version of Mike Perham's upstart sidekiq script on an Ubuntu 14.04 machine, yet almost nothing is being evaluated as expected:
Here's my modified script:
# /etc/init/sidekiq.conf - Sidekiq config
# This example config should work with Ubuntu 12.04+. It
# allows you to manage multiple Sidekiq instances with
# Upstart, Ubuntu's native service management tool.
# change to match your deployment user
setuid deploy
setgid deploy
stop on (stopping workers or runlevel [06])
respawn
respawn limit 3 30
instance $index
script
# this script runs in /bin/sh by default
# respawn as bash so we can source in rbenv
exec /bin/bash <<EOT
# use syslog for logging
# exec &> /dev/kmsg
# pull in system rbenv
export HOME=/home/deploy
echo "home is $HOME"
source /home/deploy/.bashrc
echo "path is $PATH"
cd /home/deploy/domain_freek/current
echo "user is $(whoami) and pwd is $(pwd) and rbenv is located at $(which rbenv)"
exec bundle exec sidekiq -i ${index} -e production
EOT
end script
Here's the output I get in the upstart log file:
home is
path is /usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin
user is deploy and pwd is / and rbenv is located at
/bin/bash: line 12: exec: bundle: not found
2 Changes made all the difference:
1) Add hard quotes to EOT in exec /bin/bash << 'EOT'
(credit to Mat, thanks!)
2) Instead of loading .bashrc using source, add the rbenv lines from .bashrc directly to the upstart script. Replace source /home/deploy/.bashrc
with:
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
I have no idea why those two changes made the difference, and if that's related to a newer version of ubuntu, upstart, or bash. If anyone can explain, please chime in.
I've included my full working script for anyone just looking for the answer:
# /etc/init/sidekiq.conf - Sidekiq config
# This example config should work with Ubuntu 12.04+. It
# allows you to manage multiple Sidekiq instances with
# Upstart, Ubuntu's native service management tool.
#
# See workers.conf for how to manage all Sidekiq instances at once.
#
# Save this config as /etc/init/sidekiq.conf then mange sidekiq with:
# sudo start sidekiq index=0
# sudo stop sidekiq index=0
# sudo status sidekiq index=0
#
# or use the service command:
# sudo service sidekiq {start,stop,restart,status}
#
description "Sidekiq Background Worker"
# no "start on", we don't want to automatically start
stop on (stopping workers or runlevel [06])
# change to match your deployment user
setuid deploy
setgid deploy
respawn
respawn limit 3 30
# TERM is sent by sidekiqctl when stopping sidekiq. Without declaring these as normal exit codes, it just respawns.
normal exit 0 TERM
instance $index
script
# this script runs in /bin/sh by default
# respawn as bash so we can source in rbenv
exec /bin/bash << 'EOT'
# use syslog for logging
# exec &> /dev/kmsg
# pull in system rbenv
export HOME=/home/deploy
echo "$HOME"
#source /home/deploy/.bashrc
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
echo "$PATH"
cd /home/deploy/domain_freek/current
echo "user is $(whoami) and pwd is $(pwd) and rbenv is located at $(which rbenv)"
exec bundle exec sidekiq -i ${index} -e production
EOT
end script
The default .bashrc
file on Ubuntu 14.04 has a couple lines to return immediately if the shell is running in non-interactive mode. When you remove those lines from your bashrc then source
will work as expected in upstart.
~/.bashrc (Lines to remove)
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With