Skip to content

Instantly share code, notes, and snippets.

@aloucas
Created October 6, 2016 14:30
Show Gist options
  • Save aloucas/b174c5969dd9f21b0828aea15539ce15 to your computer and use it in GitHub Desktop.
Save aloucas/b174c5969dd9f21b0828aea15539ce15 to your computer and use it in GitHub Desktop.
How to deploy Sidekiq on Ubuntu 15.10 using Upstart, rbenv and Capistrano 3 in order to make sure that Sidekiq starts on every (re)boot or deployment.

Guide: Deploying Sidekiq on Ubuntu 15.10 using Upstart, rbenv and Capistrano 3

This guide covers the process of deploying to Ubuntu 15.04 Sidekiq using Upstart for spawning and daemonizing of the processes and not systemd. Also it contains the deployment tasks for Capistrano 3 and not uses the capistrano-sidekiq gem gem as it does not defer process control to Upstart. It dictates the steps you need to follow in order to achieve sidekiq running after deployment and on system (re)boot. This will not cover how to install sidekiq on server side, redis connection etc, we assume that this has already performed and it works.

Requirements

Installation steps

1. Add the sidekiq.conf file at systems init folder

You should make sure that your deployment user deploy has sudo access to initctl. Upstart is poorly designed in that you must have root credentials to do anything with it so we'll need sudo. Therefore, add deploy to sudo group:

usermod -a -G sudo deploy

Go to /etc/init/ and paste this sidekiq.conf file: sudo nano /etc/init/sidekiq.conf

Make sure to change deploy to the user assigned with the deployment tasks in the following part:

setuid deploy
setgid deploy 

change the home path accordingly at this part:

env HOME=/home/deploy

and change the to the name of the app sidekiq will run on boot time at this part:

cd /home/deploy/apps/<your-app-name>/current

If your sidekiq relies on a configuration file you should specify it on the following line of code. Most of the times, you have queues, logfile settings etc. If you are not using a configuration file, delete from the following line the -C config/sidekiq.yml part, otherwise leave it as it is.

exec bundle exec sidekiq -i ${index} -d -C config/sidekiq.yml -e production

An example file of sidekiq configuration can be found on the sidekiq.yml gist and should be placed at <your-app-name>/config/sidekiq.yml.

An important part here to note is that using upstart without specifying a logfile, by default will log out to /var/log/upstart/sidekiq.log unless you have specified something different on your sidekiq.yml file. It is better to have all your application log files in one place, therefore, specify the logfile option on your sidekiq.yml file to the path you keep all your logs -> (ex: ./log/sidekiq.log) <- the dot there is not a typo.

---
:concurrency: 5
:logfile: ./log/sidekiq.log

Having edited all the above save and exit the sidekiq.conf file and perform a test to check if sidekiq starts using the following:

sudo start sidekiq index=0

you also have the following commands to control sidekiq processes:

sudo stop sidekiq index=0
sudo status sidekiq index=0
sudo reload sidekiq index=0

it should return sidekiq (0) start/running, process 21281 with the server process number assigned.

You can also check that sidekiq is running by:

ps aux | grep sidekiq
Go visit the logs of the application and tail them to see sidekiq starting
cd /apps/<your-app-name>/current/log
tail -f sidekiq.log

2. Add the workers.conf file at systems init folder

Go to /etc/init/ and paste this workers.conf file: sudo nano /etc/init/workers.conf

Change only the number of sidekiq processes you want to run on this machine:

env NUM_WORKERS=1

save & exit Now you have access to the following commands:

sudo stop workers  
sudo start workers   
sudo restart workers

3. Update your config/deploy.rb file with the sidekiq tasks

Go to <your-app-name>/config/deploy.rb and add the lines of this deploy.rb file. save it and perform a deploy:

bundle exec cap production deploy

If your your deployment stops asking for sudo password you should change the password settings of your deploy user in the sudoers.tmp file by:

sudo visudo

and type the following at the last line of the file:

deploy ALL=(ALL) NOPASSWD: ALL

If you tail -f the sidekiq logs as described here you should see sidekiq restarting successfully.

4. Perform system reboot and check that everything is working with upstart

The final step is to check that sidekiq starts after a system reboot, so go ahead and reboot your server:

sudo shutdown -r now

if you are on a production server that reboot might cause outages and downtime think twice before rebooting, try all these first in a staging or testing server

That's it! 💥 You should have your sidekiq processes up and running after server reboot.

You can use upstart on Ubuntu 16.04 (Although is not recommended)

The above guide can be used will success on Ubuntu 16.04 distribution but you should get upstart as it is not part of the default distribution. Beginning with Ubuntu 16.04 systmd supplants Canonical's Upstart. Therefore you need to install it by:

sudo apt install upstart-sysv

and perform the steps 1-4 of this guide.

More information:
# Sidekiq tasks
namespace :sidekiq do
task :quiet do
on roles(:app) do
puts capture("pgrep -f 'workers' | xargs kill -USR1")
end
end
task :restart do
on roles(:app) do
execute :sudo, :initctl, :restart, :workers
end
end
end
after 'deploy:starting', 'sidekiq:quiet'
after 'deploy:reverted', 'sidekiq:restart'
after 'deploy:published', 'sidekiq:restart'
# /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 manage sidekiq with:
# sudo start sidekiq index=0
# sudo stop sidekiq index=0
# sudo status sidekiq index=0
#
# Hack Upstart's reload command to 'quiet' Sidekiq:
#
# sudo reload sidekiq index=0
#
# or use the service command:
# sudo service sidekiq {start,stop,restart,status}
#
description "Sidekiq Background Worker"
# This script is not meant to start on bootup, workers.conf
# will start all sidekiq instances explicitly when it starts.
#start on runlevel [2345]
#stop on runlevel [06]
# change to match your deployment user
setuid deploy
setgid deploy
env HOME=/home/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
# Older versions of Upstart might not support the reload command and need
# this commented out.
reload signal USR1
# Upstart waits 5 seconds by default to kill the a process. Increase timeout to
# give sidekiq process enough time to exit.
kill timeout 15
instance $index
script
# this script runs in /bin/sh by default
# respawn as bash so we can source in rbenv
exec /bin/bash <<'EOT'
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
cd /home/deploy/apps/<your-app-name>/current
exec bundle exec sidekiq -i ${index} -d -C config/sidekiq.yml -e production
EOT
end script
---
:concurrency: 5
:logfile: ./log/sidekiq.log
staging:
:concurrency: 10
production:
:concurrency: 20
:queues:
- [carrierwave, 2]
- mailers
- default
# /etc/init/workers.conf - manage a set of Sidekiqs
# 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 sidekiq.conf for how to manage a single Sidekiq instance.
#
# Use "stop workers" to stop all Sidekiq instances.
# Use "start workers" to start all instances.
# Use "restart workers" to restart all instances.
# Crazy, right?
#
description "manages the set of sidekiq processes"
# This starts upon bootup and stops on shutdown
start on runlevel [2345]
stop on runlevel [06]
# Set this to the number of Sidekiq processes you want
# to run on this machine
env NUM_WORKERS=0
pre-start script
for i in `seq 0 ${NUM_WORKERS}`
do
start sidekiq index=$i
done
end script
post-stop script
for i in `seq 1 ${NUM_WORKERS}`
do
stop sidekiq index=$i
done
end script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment