Foreman is a gem that allows you to define what processes an (rails) app needs to run. For example background workers, pubsub etc.
Typically I like to deploy my applications to at least two environments: staging and production, not to mention running it in development locally. I had to do a bit of wrangling to get Forman to do this. Specifically I need to start my services using different rails environments, and Foreman does not seem have have built in support for this. (Heroku seem to not care about environments in the Procfile - I assume they have their own magic way of dealing with this)
First I set up a directory
config/procfiles
and in there I put the following to files
production.proc
-------------------
worker: RAILS_ENV=production bundle exec rake jobs:work
and
staging.proc
---------------
worker: RAILS_ENV=staging bundle exec rake jobs:work
Then I added the following Capistrano tasks into deploy.rb (which handle installing and restarting the processes as upstart scripts on my server)
namespace :services do
desc "Restart all the services"
task :restart do
run "#{sudo} restart #{application}"
end
desc "Wipe and recreate the upstart scripts - (also restarts the services)"
task :reinstall do
raise "STOP!!!" if application.nil?
begin
run "#{sudo} stop #{application}"
rescue
# don't care if we can't stop. just means it wasn't running
end
run "#{sudo} rm -f /etc/init/#{application}*"
run "cd #{current_path}; #{sudo} bundle exec foreman export upstart /etc/init -a #{application} -f #{current_path}/config/procfiles/#{stage}.proc -u #{user} -c worker=1"
# Insert command to start service at boot time NOTE this does not work on the mac version of sed which is not GNU sed
run "#{sudo} sed -i '1 i start on runlevel [2345]' /etc/init/#{application}.conf"
run "#{sudo} start #{application}"
end
after "deploy:update", "deploy:services:reinstall"
end
Now I can run cap staging deploy (I’m using capistrano-multistage) and it will stop all my services, setup up the right upstart scripts (in case I have changed the Procfiles) and restart my services