Script for starting a rails app, with some peculiarities
This was an interesting one. Thank you :)

I dug around in the rails code and poked at webrick and rack for a while and this is what I came up with:

PROJECT_DIR     = ENV['PROJECT_DIR']     || '/path/to/app'
BROWSER_COMMAND = ENV['BROWSER_COMMAND'] || 'browser http://localhost:3000 &amp;'
PORT            = ENV['PORT'].to_i       || 3000

require "#{PROJECT_DIR}/config/environment.rb"

thread = Thread.new do
  Rack::Handler::WEBrick.run Rails.application, Port: PORT
end

`#{ BROWSER_COMMAND }`

Rack::Handler::WEBrick.shutdown

thread.join


This approach is actually borrowed from rack's webrick handler.

I load the environment prior to actually starting the webrick server making any waits unnecessary for me. If that should be necessary for you, I'm sure you could add it.

Then I pretty much stuck to what you did, putting the actual server into a thread. The Handler already provides that neat shutdown method.

Oh, I also took the liberty of adding some ENV variables so you can put this script into a file and run it from where ever you want.

EDIT: In the comments Marcus pointed out, that in order to resolve the timing issue, one can set the closure (block variable) from WEBrick.run {|server|} to a thread-local variable that can be polled afterwards.

There might also be ways to exploit Celluloid for messaging between the different threads.