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 ror 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 RAILS_ENV=production VERBOSE=0 QUEUE=*
#2 RVM setup
You might have noticed that I'm not calling
bundle exec to start
unicorn, but instead I'm using
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
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
will give you additional informations about your processes.
When deploying your application you will want to restart all processes associated with your app. Running
sudo supervisorctl restart app:*
will do just that.
- 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 capistrano creates for you.
- Your production .env file should not be added to SCM. It should be copied into your application directory upon deployment.