Wildfalcon

Laurie Young: Scrum Master, Dancer, Photographer and Entrepreneur

Deploying with Foreman in multiple environments

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

Tagged as: , , ,
  • http://www.bootic.net Ismael Celis

    This is very useful Laurie, thanks!

  • http://daeltar.org Lukáš Konarovský

    Foreman decides which working path it will use based on path to procfile, so it will be set to config/procfiles and that is something you probably do not want.

    Excerpt from Foreman source code:
        @directory = File.expand_path(File.dirname(procfile))

    Quick hacky fix:

    run “cd #{current_path} && sudo sed -i ‘s//config/procfiles//’ /etc/init/#{application}-*-*.conf”

Featured Categories

Get Adobe Flash playerPlugin by wpburn.com wordpress themes