Skip to content

Managing application processes with the Foreman gem

MarkBennett edited this page Oct 18, 2011 · 7 revisions
 _______  _____   ______ _______ _______ _______ __   _          
  |______ |     | |_____/ |______ |  |  | |_____| | \  |          
  |       |_____| |    \_ |______ |  |  | |     | |  \_|          

The foreman gem was designed by David Dollar (@ddollar) from Heroku. Foreman allows you to describe a set of processes required to run your application. You can then run these processes in development, on Heroku, or when deployed to your own servers.

Installation

Installing foreman is easy. You can add it to your Gemfile:

source "http://rubygems.org"
gem "foreman"

Then bundle install. You can also install Foreman manually using:

gem install foreman

The Procfile

Your application processes are defined in a Procfile. A Procfile has a very simple format. Each line begins with the process name, followed by a colon, then the command required to execute the process.

A simple Procfile looks like this:

greeter: ruby greeter.rb
terminator: ruby terminate.rb

Now let's write those ruby files we're executing. In greeter.rb save:

while true do
  sleep 1
  puts "Greetings!"
end

And save in terminate.rb:

 sleep 5
 puts "I'll be back!"

We interact with foreman using the foreman command line interface. Verify the contents of your Procfile by entering:

foreman check

If all goes well you'll see the message:

valid procfile detected (greeter, time)

This indicates Foreman processed your Procfile and found two processes called greeter and time.

Starting your application processes

Launching the processes defined in your Procfile is easy. Just type:

foreman start

Each process in the Procfile will spin up and output to the console in a different color. I can't show you the colours in this wiki but trust me this is colourful on the console:

15:42:21 greeter.1     | started with pid 6493
15:42:21 terminator.1  | started with pid 6494
15:42:22 greeter.1     | Greetings!
15:42:23 greeter.1     | Greetings!
15:42:24 greeter.1     | Greetings!
15:42:25 greeter.1     | Greetings!
15:42:26 terminator.1  | I'll be back!
15:42:26 greeter.1     | Greetings!
15:42:26 terminator.1  | process terminated
15:42:26 system        | sending SIGTERM to all processes

The output of the processes is interleaved together but the colours make them easy to distinguish.

Notice that as soon as one process terminates, all of them terminate since it's assumed you require all of them to run your app.

You can also specifiy the number of instances of a process to run using the -c flag:

foreman start -c greeter=2,terminator=0

This will run two greeters but no terminator. You'll need to CTRL + c to stop this after you start it.

Exporting your processes

You can export the contents of your Procfile to an inittab or upstart service on Linux, and a bluepill config on Mac OS X. Just try one of these commands:

foreman export inittab
foreman export upstart /etc/init
foreman export bluepill

You can use the -c flag to control the number of processes, just like you did with foreman start. There are lots of other options you can specify to control the way your processes are exported, checkout the Foreman manual for a list.

Extra credit

Sometimes you might have multiple Procfiles associated with a project. For example, I have a bunch of processes I only run on my Mac which Ubuntu users don't care about. In this case I use a second Procfile.mac and run it with:

foreman start -f Procfile.mac

The -f flag works with all the foreman commands.

You may also want to specify parameters like directory locations which are unique to your host. You can do so using the foreman environment file, .env. This file contains key:value pairs which are set as environmental variables you can access from the commands in your Procfile.

For example, let's say you want to specify a different temporary directory depending on your host. Set the TMP_DIR variable in your .env file:

TMP_DIR=/tmp

Now if we have Procfile which uses this environmental variable, call it Procfile.with_env, it will be able to use this environmental variable in the processes it defines.

echo: echo $TMP_DIR

Give this a try with foreman start -f Procfile.with_env and you'll see it works.

Note that for the time being, the .env on works when running foreman with foreman start. You'll need to either set these environmental variables yourself in production or add reasonable defaults to your processes. This may be changing soon though.

References

Now that you know enough about foreman to get you started, check out these resources: