How to configure different environments in Rails
When working in software development, at some point you must have heard about the production environment and asked yourself, what does that mean? Many companies use different environments for various purposes depending on the engineering guidelines and the testing strategy. In this article, I’m going to tell you about the different environments, why companies use them, and how to configure them for your Rails application. On top of that, I will also tell you about other useful configuration files and how to store and read credentials in your app.
Most companies have some guidelines about how to release code. Some make continuous integration and deployment, meaning every commit that is pushed to the main branch is deployed immediately, others have release cycles every number of weeks, usually two, and in between those cycles, the code that is going to be released (release candidate) gets deployed to different environments to run different types of tests (regression, smoke, integration, end to end), and some other times you will need to do debugging with production-like data and there is usually an environment used for that purpose. For all these reasons and many more, there is the need to have several environments and with them different configurations.
Let’s see some of the typical environments used in software development:
- Dev: It is an environment that is used to deploy code that is being developed, it is a step beyond the Local environments and is used to test if the code and its dependencies deploy correctly. In this environment, the code changes frequently and multiple people have access to it.
- Staging: It has different purposes in different companies. In some companies, it is an environment that is very close to production in terms of resources, hardware, and architecture. In other companies, it is an environment where you test some special parts of the code so it changes less often than Dev. This is typically the step before releasing code to production and it might have production-like data.
- Pre-production: Some companies don’t use it and go directly from staging to production, but this environment is the closest to production and sometimes is a snapshot of the production environment from the day before so you can do some debugging with production without actually touching production.
- Production: This is the most sacred environment and the one with the least changing code, it is not supposed to be touched directly and should only change with PRs approved by a review process to ensure nothing breaks. Sometimes, if the change is too big or touches critical parts of the application, it is required that the code is tested in lower environments to ensure that nothing breaks and guarantee that everything was accounted for before releasing it to production. It is the environment where all your users will interact with your application, that is why it is the most guarded one.
- Testing: Testing is generally the environment where automated tests are run, it is used by the QA department or automated workflows to run tests and determine if something has broken.
To set the environment in which the application will run, Rails uses the environment variable RAILS_ENV
, and you set it to the name of the configuration file for that environment so it will pick up the setup for it.
We have talked about configuration files, now let’s see what they are. Every Rails application has a folder /config/environments
, which is where the configuration files for different environments live. The default ones are development, testing, and production, but you can create files for each one of the environments that we saw before. You can check what are all the options that you can configure in those files in the configuration documentation.
There is also a gem that helps with environment configuration without the need to have global variables called Configatron, it creates an additional layer on top of the application configuration but it has a lot of features that make it very powerful, if you want to learn more about it visit their GitHub repo.
In addition to the environment configuration files, some gems need additional configuration specific to the objects that the gem uses, for this purpose Rails offers the initializer files. An initializer is any Ruby file stored under /config/inirializers
in your application. You can use initializers to hold configuration settings that should be made after all the frameworks and gems are loaded, such as options to configure settings for these parts. If an initializer has code that relies on code in another initializer, you can combine them into a single initializer instead. Rails also supports the numbering of initializer file names, but this can lead to file name churn. Explicitly loading initializers with require is not recommended, since it will cause the initializer to get loaded twice.
Now I want to tell you about a special configuration file that Rails has within the path /config/initializers/filter_parameter_logging.rb
, this file allows you to redact the data displayed for specific attribute names when printed to the console. You can add patterns to it and also remove the ones that come as the default behavior for Rails but you don’t want them to be redacted.
The last thing I wanted to talk about is credentials and how they work in Rails. Rails can use encryption for credentials, application data, and communication, for this to work you have to create a key that will be used for the encryption/decryption of data. There are two ways of telling the application the value for the key, the first one is to set it as the environment variable RAILS_MASTER_KEY
for the machine where the application is deployed, and the second way is to have a key file in the /config/credentials
folder with the name of the environment the application is being deployed to, this key files are created automatically when you run the rails credentials:edit -e <environment_name>
command. You have to be very careful where you store the keys because they are the backbone of the encryption for your application, if you make them public then your application security is compromised, for this reason, make sure the *.key
files are excluded from the repository and shared only with the necessary people. Another component of Rails’ encryption is the secret key base, which is used as a salt to encrypt the data. To create one, run the command `rails secret`, and then you can add it to the SECRET_KEY_BASE
environment variable or the credentials file under the secret_key_base
.
With all this in mind, we can start talking about the credentials file. When you run the command to edit the credentials it also creates the encrypted file with the credentials information in YAML format, in it, you can store anything that you consider shouldn’t be publicly accessed, like API keys or usernames and passwords for connecting to applications. This credentials-encrypted file will be committed to the repository and the application will decrypt it using the key file. To access the information inside the file you just have to use the namespace Rails.credentials['key']
.
Now you know a little bit more about Rails environment configurations and encrypted credentials for your Rails applications and I invite you to put them into practice in the next project you develop. Thank you for reading the article and if you liked it give a clap and check out my other articles.
References