note: this post was updated on 05.03.2012 to reflect changes made to supervisord support.
When I’m developing a Ruby on Rails application I like having my external services configured inside my SCM. This eases the burden of documenting what must be executed in order to have a fully running application. It also helps deploying the application to the production- or staging environment since foreman supports exporting to process monitoring tools like upstart.
Today I want to share a new export feature which was recently added to foreman: supervisor. I’m going to walk through a sample Ruby on Rails project configuration consisting of unicorn and resque.
#1 production environment & Procfile
I like to keep a separate Procfile for each environment which allows me to tweak it if needed without breaking foreman for a different environment. Thus my foreman Procfile is called Procfile.production
for the production environment.
# Procfile.production
unicorn: /home/app-user/.rvm/bin/app_bundle exec unicorn -c config/unicorn.rb -E production
worker: /home/app-user/.rvm/bin/app_bundle exec rake environment resque:work
Also following the foreman documentation I have the environment used for export in a separate file, called .env
.
# .env
RAILS_ENV=production
VERBOSE=0
QUEUE=*
#2 RVM setup
You might have noticed that I’m not calling bundle exec
to start rake
or unicorn
, but instead I’m using app_bundle exec
.
app_bundle
is a RVM wrapper script which helps me loading the correct version of Ruby as well as the correct gemset. You can create that wrapper by executing the following command:
rvm wrapper 1.9.3-p125 app bundle
If you are using an RVM user installation the script will be placed in /home/app-user/.rvm/bin
, executing
which app_bundle
will tell you the correct path.
#3 foreman export
You can now export your processes for supervisord by issueing the following command:
foreman export supervisord /etc/supervisor/conf.d -a app -u app-user \
-l /home/app-user/shared/log -f /home/app-user/current/Procfile.production -c worker=2,unicorn=1
This will export two instances of the worker process, and one for unicorn. The resulting supervisord configuration should look like this:
[program:app-unicorn]
command=/home/app-user/.rvm/bin/app_bundle exec unicorn -c config/unicorn.rb -E production
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/app-user/shared/log/unicorn-1-out.log
stderr_logfile=/home/app-user/shared/log/unicorn-1-err.log
user=app-user
directory=/home/app-user/current
environment=PORT=5000,VERBOSE=0,QUEUE=*,RAILS_ENV=production
[program:app-worker-1]
command=/home/app-user/.rvm/bin/app_bundle exec rake environment resque:work
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/app-user/shared/log/worker-1-out.log
stderr_logfile=/home/app-user/shared/log/worker-1-err.log
user=app-user
directory=/home/app-user/current
environment=PORT=5101,VERBOSE=0,QUEUE=*,RAILS_ENV=production
[program:app-worker-2]
command=/home/app-user/.rvm/bin/app_bundle exec rake environment resque:work
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/app-user/shared/log/worker-2-out.log
stderr_logfile=/home/app-user/shared/log/worker-2-err.log
user=app-user
directory=/home/app-user/current
environment=PORT=5102,VERBOSE=0,QUEUE=*,RAILS_ENV=production
[group:app]
programs=app-unicorn,app-worker-1,app-worker-2
#4 restarting supervisord
You can now have supervisor pick up the new configuration using
sudo supervisorctl reread
sudo supervisorctl update
If you want to know if your app works as expected calling
sudo supervisorctl
will give you additional informations about your processes.
#5 Deployment
When deploying your application you will want to restart all processes associated with your app. Running
sudo supervisorctl restart app:*
will do just that.
finishing words
Supervisord support is currently only available in the edge version of the gem. No new version has been made available by now.- I’m assuming you are deploying your app using a directory structure similar to that which either Capistrano or Mina creates for you.
- Your production .env file should not be added to SCM. It should be copied into your application directory upon deployment.
Happy hacking!