Skip to content

Instantly share code, notes, and snippets.

@andyl
Created April 28, 2012 00:24
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save andyl/2514573 to your computer and use it in GitHub Desktop.

Overview

I love Foreman, but need some additional capabilities:

  • upstart/init script with different options than foreman supports (dependencies)
  • monit config files
  • separate export templates per app-type
  • separate start and stop commands for some app-types

Inspiration for Enhanced Foreman

I like how the Vagrantfile lets you specify many configuration settings, and keeps the command-line options simple.

Other considerations:

  • for me it would be handy to specify start/stop/reload commands in the Procfile
  • as a developer, I would love Foreman to generate sample templates that I could hack on
  • I would love Foreman to be smart enought to clean up the exported config files

Enhanced Foreman: Command Line Options

Tasks:
  foreman check                   # Validate your application Procfile
  foreman export FORMAT LOCATION  # Export the application to another process management format
  foreman help [TASK]             # Describe available tasks or one specific task
  foreman run COMMAND             # Run a command using your application environment
  foreman start [PROCESS]         # Start the application (or a specific PROCESS)
  --- these are new !! ---
  foreman list                    # lists all supported formats
  foreman init                    # create a placeholder Procfile
  foreman generate [FORMAT]       # dump sample code and templates to ./foreman/...
  foreman cleanup FORMAT LOCATION # remove generated config files
  foreman start FORMAT            # runs the start command associated with FORMAT
  foreman status FORMAT           # runs the status command ...
  foreman stop FORMAT             # runs the restart command ...
  foreman reload FORMAT           # runs the reload command ...
  foreman restart FORMAT          # runs the restart command ...

Options:
  -f, [--procfile=PROCFILE]  # Default: Procfile
  -d, [--app-root=APP_ROOT]  # Default: Procfile directory
  --- new!! -----
  -e, [--environment=ENV]    # Default: production

Enhanced Foreman: Procfile

# standard 'long form' block
Process::Config.define do |config|

  # ----- 'export' configuration -----

  config.export.specify "upstart" do |upstart|
    upstart.start_command  "/sbin/init start <%= app_name %>"
    upstart.stop_command   "/sbin/init stop <%= app_name %>"
    upstart.status_command "/sbin/init status <%= app_name %>"
    upstart.emits          "starting <%= app %>"
    upstart.depends        "reboot db_crash"
  end

  config.export.specify "monit" do |monit|
    monit.memory_limit = "350MB"
    monit.alert_address = "joe@yourco.com"
    monit.reload_command = "monit reload"
  end

  # ----- 'app' configuration -----

  config.app.specify "web" do |web|
    web.exports_to ['monit', 'upstart', 'metrics']
    web.start_command = "bin/passenger --log_file shared/log/<%= name %>.log"
  end

  config.app.specify "faye" do |faye| 
    # use Ruby to customize per-environment...
    faye.export.monit.memory_limit = ForemanEnv.production? ? "20MB" : "10MB"
    faye.exports_to ['monit', 'upstart']
    faye.start_command = "script/faye_script.sh"
    faye.port = 2343
  end

end

# 'short form' that over-rides previous setting
Process::Config.specify("web").start_command "bin/unicorn"

Enhanced Foreman: Export Templates

default_upstart.erb

start on runlevel [2345]
stop on runlevel  [!2345]
expect daemon
respawn
exec <%= @start_command %>

faye_upstart.erb

start on reboot 
expect daemon
respawn
pre-start script
  emit starting_faye
end
exec <%= @start_command %> --port <%= port %>

default_monit.erb

check process <%= app_name %> with pidfile <%= pidfile %>
  start program = "<%= @start_command %>"
  stop program = "<%= @stop_command %>"

faye_monit.erb

check process <%= app_name %> with pidfile <%= pidfile %>
  start program "/etc/init.d/<%= app_name %> start"
  stop program  "/etc/init.d/<%= app_name %> stop"
  if failed port <%= port %> then restart
  if 5 restarts within 5 cycles then timeout
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment