While building a web app you'll often need to have access to different variables depending on the setup (or environment). For example, your local machine, the staging/testing server, and development servers are all different environments.
On each of these environments you might need different settings. On your local machine your app might connect to a
localhost database, while staging and development connect to AWS DynamoDB or MongoDB Atlas. Environment variables give you the ability to have different settings across these environments.
Environment variables are typically stored in a
.env file in your project directory consisting of key/value pairs. On your local machine the
.env file contains key/values for your local setup, while the
.env on staging and production contain the same keys, but values specific to their environment. Ex:
// Local .env DB_URL = mongodb://localhost:27017/myapp // Staging .env DB_URL = mongodb://<NAME>:<PASSWORD>@cluster0-shard-00-00-pwdcu.mongodb.net:27017,cluster0-shard-00-01-pwdcu.mongodb.net:27017,cluster0-shard-00-02-pwdcu.mongodb.net:27017/<DATABASE>?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin // Production .env DB_URL = mongodb://<NAME2>:<PASSWORD>@cluster0-shard-00-00-pwdcu.mongodb.net:27017,cluster0-shard-00-01-pwdcu.mongodb.net:27017,cluster0-shard-00-02-pwdcu.mongodb.net:27017/<DATABASE>?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin
The connection settings in your app make use of these variables to connect to the different database depending on the environment. If you're in node,
process.env.DB_URL would reference the DB_URL variable.
.env file needs to contain different values depending on the environment it's not recommended to commit it to
git. The file might also contain sensitive data you don't want to share with the public. For these reasons most projects add
.env to the
.gitignore file so the
.env file isn't tracked in
This setup requires you to manually update the
.env file across environments when changes are made. That is, since the file isn't tracked in
git any changes to the
.env file are only made to your local version. Any new key/value pairs added to your
.env file will need to have the same key and appropriate value added to the staging and production
.env files. This can be done via
ssh or through a hosted service's dashboard (like Heroku) in many cases.
What about Travis?
If you're using Travis CI to deploy and test your code Travis needs access to the same environment variables. The
.travis.yml config file accepts a
env key for adding environment variables:
env: DB_URL = mongodb://<NAME>:<PASSWORD>...
but this completely defeats the purpose of untracking the
.env file in
git as your private info is now available to the public in the
Thankfully Travis allows for encrypting environment variables, allowing you to add environment vars to
.travis.yml without giving away sensitive data.
First, install the
gem install travis
In your project directory run:
travis encrypt DB_URL=super_secret
This will return an encrypted string which can be added to the project's
There's also a
--add option which will add the secure key to your
.travis.yml file for you:
travis encrypt DB_URL=super_secret --add env
.travis.yml file will now contain an entry of:
env: secure: MBxG/gsqeyONzA7wbWKACzv...
Travis will decrypt this into the original key/value pair of:
Once the encrypted environment variable is added to the
.travis.yml file you'll commit your changes and carry on with your normal process. Travis now has access to your environment variables and they'll remain secret from others even if your project repo is public. More info and options available in the Travis CI environment variables docs.