How to Create Rails Environment
When David Heinemeier Hansson (DHH) was developing Basecamp and creating the Rails framework, he most definitely faced the problem of “how do I separate the configuration and environment settings for development and production deployments of the application”. Mainly, the big issue, when I was be coding, was keeping the configuration for the development and production database easily accessible and swappable. I would say that all (99.999%) of software developers have faced this problem and created/found solutions to help solve it.
Rails offers an elegant solution to this challenge, by providing you with a way to separate these environment into separate configuration files.
Understanding The Environments
Rails comes with concept of separating the environments that you application will be executed in. When you develop you application you are said to be in the DEVELOPMENT environment, when you run your tests you are in the TEST environment and when you deploy you server to production the code is run in the PRODUCTION environment.
This can be easily seen in the default database configuration file, generated when you create a Rails application.
Warning: The database defined as “test” will be erased and
re-generated from your development database when you run “rake”.
Do not set this db to the same as development or production.
As you can tell, the default database is SQLite3 and Rails generates names for you database, which are closely related to the environment name.
If you create Rails application with MySQL as the default database, the names generated for you will follow this format.
So the pattern will be ‘yourapplicationname’ with ‘enviromentname’ appended to it. This pattern is commonly accepted by the Rails Developers and I suggest you don’t change it, unless you are working with a legacy database, in which case only your production database name should change.
** TIP: ** leave your development and test database names unchanged, they will not affect how your application is developed and tested and make sure the other developers working on the same app don’t need to modify the settings on their own computer.
** TIP: ** For simplicity’s sake, I would by default use SQLite3 as the test and development database.
Inside every Rails app, inside the config directory, there exists an environments directory. This is a place where application settings specific to an environment are defined.
By default, three files are generated there:
Each file contains a set of configuration options that define how a Rails application is to be executed.
# Settings specified here will take precedence over those in config/application.rb
# In the development environment your application’s code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don’t have to restart the webserver when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.considerallrequestslocal = true
config.actionview.debugrjs = true
config.actioncontroller.perform_caching = false
# Don’t care if the mailer can’t send
config.actionmailer.raisedelivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.actiondispatch.beststandards_support = :builtin
This is an example of a development.rb environment configuration file. Some of the settings included here are:
- whiny_nils – ensures that errors on nil objects are logged
- actionmailer.raisedelivery_errors is set to false – don’t tell me that emails can’t be delivers, since its a develoment environment
- disable cache – makes every class be reloaded on each request
The production.rb file for the production environment, is much more stricter and enables caching, hides some of the nasty errors from being displayed to the user and generally makes your application run faster.
In the test enviroment, test.rb resembles the development.rb since you want error messages to be available and logged for debugging purpose, however, it performs some caching to make tests run faster.
Every generated environment file includes this commented line at the top of the file.
Settings specified here will take precedence over those in config/application.rb
This means that you are able to create application wide settings in the application.rb file and then override it based on which environment your application is in.
Running The App in Different Environments
A Rails application determines on its own, which environment it should be running in. It looks for an environmental variable RAILS_ENV to tell it which environment it should run in. If the variable is empty or does not exist, it runs using the settings for the DEVELOPMENT environment.
You can start a Rails server in a specific environment by setting the RAILS_ENV variable.
$ rails s
This will start the Rails app in the production environment.
When you run your Tests using rake test command, Rake automatically sets the environment to TEST, you don’t have to do anything.
** TIP: ** You might be tempted to run a rails server in the TEST environment. DON’T DO IT. The TEST environment is only for testing.
When you application is deployed on the production server, the setting of the PRODUCTION environment is done through PassengerMod (For apache) or NginX (EngineX) server. Usually, they treat any application deployed with either of these as being in PRODUCTION environment, so you don’t have to do anything extra. If you want to specifically change the environment, you can do so using one of their configuration directives (see their documentation).
Creating Custom Environments
Sometimes you want to create a custom environment. Personally, I only see it useful to have a STAGING environment, an exact copy of PRODUCTION. This serves only as a naming distinction. You might have other reasons, but I would suggest keeping everything as default, they are good enough for most projects.
So, to create a new environment for your rails application, just copy and past one of the environment files inside config/environments directory, rename it to the environment you want. Then add an environment definition to the config/database.yml for that environment and you are ready to roll.
Example of database.yml:
This was a brief explanation of how environments work and why they are there. If I missed something, don’t hesitate to ask questions in the comments.