Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple environments for Ruby application

I've been writing Rails apps for so long that I'm suddenly stuck with something you get for free with Rails: environments.

That is to say, you can run the Rails app locally and by default, RAILS_ENV (or Rails.env) is "development". And if you are running your specs/tests, it's "test" and when you deploy to your production server, you set it up to run as "production".

This is particularly useful when you have config files. Also useful for the Gemfile to differentiate gems for certain environments.

So now to my question: I'm writing a pure Ruby app and I don't know the best way to set it up so that I can still have the multiple environments? I want to set up config files for 3rd-party services (like MongoLab/Iron.IO/etc.) but I want them set up with "development", "test", "production", etc. And then I want to be able to run the app from various environments.

I know I could just manually handle it via command-line environment variables, but I'm wondering if there are best (better?) practices for this? Any gems that help with this? Or any recommendations for how to structure environment handling for a pure Ruby app?

Thanks,

like image 291
Dan Sharp Avatar asked Apr 28 '15 16:04

Dan Sharp


People also ask

What are Rails environments?

By default rails has 3 environments, development , production and test . By editing each file you are editing the configuration for that environment only. Rails also has a configuration file in config/application. rb .

Where are Ruby environment variables stored?

You store separate environment variables in config/development. rb , config/testing. rb and config/production. rb respectively.

What is ENV in Ruby?

ENV is a hash-like accessor for environment variables.


1 Answers

You could do something quite like the way rails does it:

class AppEnvironment

    def initialize(env = :production)
      @name = env.intern
    end

    def development?
        @name == :development
    end 

    def test?
        @name == :test
    end

    def production?
        @name == :production
    end
end

app_environment = AppEnvironment.new( ENV['APP_ENVIRONMENT'] )

Then you set the environment var via rake tasks.

namespace :myapp do
  desc "Run a development server"
  task :server => :environment do
    ENV['APP_ENVIRONMENT'] ||= "development"
    # ...
  end

  desc "Run a bunch of tests"
  task :test => :environment do
    ENV['APP_ENVIRONMENT'] ||= "test"
    # alternatively do this in `spec_helper.rb`
  end

end

Added.

Using different sets of gems per environment is pretty easy with Bundler.

You might recognize this line from config/application.rb in rails:

Bundler.require(:default, Rails.env) # Rails.env is just a string

This tells bundler to require all gems in a specific group in addition to gems declared outside a group.

gem 'foo'

group :test do
  gem 'rspec'
end
like image 129
max Avatar answered Oct 19 '22 05:10

max