Introducing Dotenv Validator: A Lean Library to Validate your Environment Variables
We are excited to share a new gem for the Ruby community:
dotenv_validator! A library that will help you validate
that the values in your environment are valid according to the comments in
At OmbuLabs (the company behind FastRuby.io) we embrace the Twelve-Factor Methodology for all of our internal, open source, and client applications. One of the principles of this methodology is to store configuration in the environment.
The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.
We have been using the
dotenv gem for years and we really like it. It works
- You define a
.envfile in your application directory
- Dotenv loads them before loading your application code
- Then you can use those values like this
Unfortunately it doesn’t help you validate that you have all the environment variables that you need to run an instance of your application. So sometimes you end up with cryptic messages when you try to boot your Rails app without all the right environment variables.
When designing this library, we took into account another file that has been
very useful over the years:
The goal of the sample file is to help new developers get started with your
bin/setup scripts usually look like this:
puts "\n== Copying .env file ==" unless File.exist?('.env') FileUtils.cp '.env.sample', '.env' end
Basically, if the
.env file does not exist it will use the
to create the
.env.sample may look like this:
.env.sample ADMIN_USERNAME=foo # required ADMIN_PASSWORD=bar # required
The comments at the end of each line do not get loaded by
Dotenv, so they
can be used for documenting details about the variables (e.g. date format, length)
We decided to use this documentation “as executable code” which will be
Every time someone adds a new variable to the application, they must:
- Add a line to the
.env.samplefile with the right comment
- Add a reference to the environment variable somewhere in the application
For example, when we launched the landing page for our roadmap package (a code audit to plan your next upgrade project), we decided to add these two new variables:
# .env.sample ROADMAP_PRICE=3900 # required,format=int DISCOUNT_AMOUNT=500 # required,format=int
We were already using
dotenv to load
our env variables. So then we only had to add
dotenv_validator to our
Then we had to add this file to our initializers directory:
# 01_dotenv_validator.rb puts "Validating environment... 🧐🧐🧐" DotenvValidator.check! puts "Your environment is in good shape! 🚀🚀🚀"
The name of the file is important: We named the file so that it is the first initializer it runs. This is the safest way to go because other initializers may depend on environment variables.
When we tried to load the application without the right environment variables, this is what we saw:
Validating environment... 🧐🧐🧐 Exiting /Users/etagwerker/Projects/fastruby/dotenv_validator/lib/dotenv_validator.rb:73:in `check!': Missing environment variables: ROADMAP_PRICE, DISCOUNT_AMOUNT
No more cryptic messages! Now you can quickly learn that the app won’t work as expected if you don’t set the right environment variables.
DotenvValidator stops the boot process and makes us add the right environment
variables to our
In order to use
dotenv_validator you have to keep a
.env.sample in the root
of your application directory. That file should be checked in to the repository
and updated accordingly every time you add (or remove) an environment variable.
Comments need to use the following syntax:
# requiredfor environment variables that must be in your environment before you can run the application.
# format=emailfor environment variables that must have a particular format. There are many supported formats for your variables (it even supports regexps!)
You can combine rules like this:
# required, format=email
.env.sample was a design decision. We didn’t want to add yet another
file or DSL to our applications. If you are okay with that,
envied is a pretty cool solution for the
same problem! 🤓
4. Final Thoughts
This new gem is quite lean (less than 120 lines of code) and it solves the problem of missing or invalid environment variables in your environments. It’s pretty straight-forward and it relies on existing best practices:
- Using environment variables
- Keeping a
.env.samplefile in your repo to document them
If you’ve been bitten by missing environment variables in the past, give it a try and let us know what you think!
Finally if you want to get started with open source we have a list of beginner-friendly issues on GitHub.
Thanks for reading all the way to here and thanks to all the contributors who helped with this gem! You rock. 🤘