Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sinatra configuring environments on the fly

I have successfull written a little Sinatra application and already successfully deployed it on heroku.

However I want to run that application in development mode on my local computer and I want to have it production mode on heroku once I push it to the remote repository.

Currently I can achieve either one of thos options. When I change my config.ru to the following values:

require 'rubygems'
require 'sinatra'
require 'sinatra/reloader'
require "./calc.rb"

enable :logging
set :environment, :development
set :port, 4567

I'm able to run it locally (on port 4567) via ruby config.ru. When I change the config.ru to this:

require 'rubygems'
require 'sinatra'
require 'sinatra/reloader'
require "./calc.rb"

enable :logging
set :environment, :production
set :port, 4567
run Sinatra::Application

I'm able to get it to run on Heroku (on port 80).

But I can not use the same configuration for both development and production.

I would like to have something like:

ruby config.ru dev for development and ruby config.ru for production.

Additional information:

When I try to run the production config.ru on my local machine I get:

$ ruby config.ru
(eval):2:in `method_missing': undefined method `run' for main:Object (NoMethodError)
        from (eval):4:in `__send__'
        from (eval):4:in `method_missing'
        from config.ru:10
like image 714
leifg Avatar asked Apr 29 '11 12:04

leifg


2 Answers

C:\>type tmp.ru
require 'sinatra'
configure(:production){  p "I'm production" }
configure(:development){ p "I'mma dev mode" }
configure(:sassycustom){ p "I'mma own mode" }
exit!

C:\>rackup tmp.ru
"I'mma dev mode"

C:\>rackup -E development tmp.ru
"I'mma dev mode"

C:\>rackup -E production tmp.ru
"I'm production"

C:\>rackup -E sassycustom tmp.ru
"I'mma own mode"

C:\>rackup -E notdefined tmp.ru

If you don't specify an environment, development is used by default. You can specify any environment name you want, though 'production' is very common. If you specify an environment that you don't configure, no configuration block will match. (It might be a mistake on your part, but it's not an error caught by the code.)

Note that the Sinatra documentation says that setting RACK_ENV environment variable will be used if available. This used to not work, but some time in the last few years it has been fixed!

If, for example, you can set an environment variable for your service, you can control the mode.

like image 173
Phrogz Avatar answered Nov 14 '22 04:11

Phrogz


You can also grab ENV['RACK_ENV'] in your config.ru and use that configure your app differently. On Heroku it should run in production by default and if you rackup to fire up your server it will be development by default. Here's some sample code from one of my apps that runs in both environments with the same config file:

#\ -p 4567
require 'bundler'               # gem requires
Bundler.require(:default, ENV['RACK_ENV'].to_sym)  # only loads environment specific gems
if ENV['RACK_ENV'] == 'production'           # production config / requires
  require './lib/middleware/exceptionmailer'

  use Rack::ExceptionMailer, 
    :to => ['[email protected]'],
    :from => '[email protected]',
    :subject => 'Error Occurred on Rack Application'

else                            # development or testing only
  use Rack::ShowExceptions
end

This way, Thin or Passenger or whatever will pick it up and the right modules will get loaded in production but you can do other configuration for development.

like image 44
Evan Lecklider Avatar answered Nov 14 '22 05:11

Evan Lecklider