Multiple Environments on Heroku

It is my understanding that the following is “The Rails Way” for setting up a staging environment.

$ cp config/environments/production.rb config/environments/staging.rb
$ atom config/environments/staging.rb # make whatever changes you need

Any sensitive data or data you may want to change without having to push a new version of the app should be placed in environment variables.

However, Heroku is recommending the following:

Your “staging” app or any other custom environments should be run with RAILS_ENV=production to minimize differences in behavior.

Now I know thoughtbot Learn does it “The Rails Way”. Can I get your thoughts on Heroku’s recommendation and whether or not I should be following it? Advantages v Disadvantages will be useful.

Hey @dwaynecrooks, I recently read the same Heroku post. It seems much better to do it ‘The Rails Way’ and set RAILS_ENV=staging, however I wouldn’t have wildly different settings in the staging config file for things like assets handling and caching classes.

I keep the behavior the same as production but handle the environment variables separately.

I run a production app on Heroku along with a staging area. I use different S3 buckets for file uploads on staging so I need to set different environment variables for them. I use Figaro and that sets all the Heroku vars by detecting the environment.

I think the main intention behind the Heroku recommendation is to keep the behavior of the app consistent between staging and production.

1 Like

Thanks for your thoughts.

Should I also be setting RACK_ENV=staging? I know Rails gives precedence to RAILS_ENV. But I’m asking in terms of a precaution.

I started off using Figaro but dotenv seems a better fit in my projects since I also use Foreman which can be configured with a .env file in development. This allows me to keep all my development environment variables in one file.

I’m not sure how RACK_ENV is referenced on Heroku Cedar. Hopefully someone more knowledgable can jump in and answer that. I’ve never had any issues with just setting RAILS_ENV.

I should look into dotenv, but I do like the convenience of having all my variables for all environments in one application.yml file with Figaro.

Do you use dotenv for setting production vars too?

With dotenv-deployment you can set your production environment variables with a .env.production file.

Actually with dotenv you need to also set RACK_ENV since it takes precedence when determining the file to use. See the source.

We use suspenders to generate our new projects, which sets up a staging config file like so:

require_relative 'production'

Mail.register_interceptor(
  RecipientInterceptor.new(ENV.fetch('EMAIL_RECIPIENTS'))
)

So the staging configurations actually uses the production configuration and then applies specific overrides where necessary. This keeps us from having to make updates in multiple files when we want to change something in both places.

@derekprior That’s really cool. I didn’t know it could be done so elegantly.