Tired with starting many things? Try Foreman now!

on Rails, Foreman, Procfile

Nowadays, almost Rails applications have more than a web process (start with rails s). They often contain a web process (rails s) and some background processes (Delayed Job, Resque...).

So far so good, this helps us to improve application performance or UX. But, how can we start our application, assume that we have 1 web process, 3 Delayed Job workers (for 3 different queues) and 1 Clock process for scheduling? You may said: it is so easy, just some commands

bundle exec rails s
bundle exec rake jobs:work --queue=mailer
bundle exec rake jobs:work --queue=importer
bundle exec rake jobs:work --queue=tasks
bundle exec clockwork clock.rb

It seems easy! But not convenient! Imagine that you will need to open 5 terminal tabs and run above 5 commands multiple times each day. Unless you have special hobby with repeating them, you will pray or find for easier way to start your application.

Solution

Of course, you can use shell script to simplify above process but you will meet many issues, such as: stop them, view logs...

The best solution that I know is using Foreman. It helps us to run as many processes as we want with only 1 command as well as stop all of them with 1 Ctrl + C. It also shows logs of all processes with different color for each process.

Using foreman is simple

  • Add foreman gem to your Gemfile
  • Run bundle install
  • Create Procfile file in your application root
  • Add your commands to Procfile
  • Run foreman start

Example Procfile for above 5 commands

web: bundle exec rails s
mailer_worker: bundle exec rake jobs:work --queue=mailer
importer_worker: bundle exec rake jobs:work --queue=importer
tasks_worker: bundle exec rake jobs:work --queue=tasks
clock: bundle exec clockwork clock.rb

As you can see, each line of Procfile contains 2 parts: <process type>:<process command>

  • Process type (web/mailer_worker/clock...): type of process, it is not needed to be in a predefined list, name it anything compatible with you
  • Process command: command to start the process. Because Procfile can also be used (or exported to be used) on production environments (Heroku is an example), some of them don't install gems to global environment but install gems to local place like vendor, so we need to use bundle exec to run commands related to gems in Gemfile. Research about bundler to know more about the bundle exec.

Notice: web: bundle exec rails s in above Procfile will start rails server on port 5000 instead of 3000 because foreman assign ports from 5000 and each process type has 100 port slots. So, with above Procfile, web type will have port 5000, mailer_worker will have port 5100 (worker doesn't need a port but foreman still give it port slots to make it consistent) and so on... You can change rails s port by adding -p option, but you should not do it if you are using Heroku because Heroku expects default ports of foreman.

When I mention 100 port slots for each type, you may have a question: "What is it for? I see the commands create only 1 process, no need to have 100 port slots". Foreman does this because we can start multiple process for each process type (that is also why I called it process type instead of process name).

In above Procfile, if we want to have 2 importer_worker and 3 tasks_worker, we will start Foreman with command

foreman start -c importer_worker=2,tasks_worker=3

Default process count for each type is 1, so we don't need to specify process count for web and clock type.


A full stack developer with Ruby on Rails as the main framework. Eager to learn and share.