Should I commit .env file to GIT?

Published Sep 21, 2022. 3 minutes to read.
Tagged with SystemsConfig.

The short answer

Yes, please, always commit your .env file to GIT. IF you know what you are doing. If not, continue reading.

The long answer

The .env of your app should contain sane development defaults, and be committed to version control.

Aim to ship your software projects working “out-of-the box” short of really complex cases where mocking external services and such is not possible for some reason - however, even in these cases, your software should ship with “majority-defaults” in .env.

This gives everyone working with your software an up-to-date reference of all configuration AND keeps it universally maintained. Having .env with sane defaults committed to version control will almost nearly ensure that a) your config reference is always up-to-date b) NEW sane defaults will always apply to everyone who uses the latest revision of your software - saving people work and headache.

Please do not use .env.example and similar while having .env in .gitignore.

Ship defaults in .env, and only ask those working on your project (including yourself) to override what NEEDS to be overridden locally.

If for any reason not all configuration can be shipped with sane defaults in .env (ex: you absolutely MUST use a live 3rd party service X that is not mockable - which is probably just you being a bit lazy) - simply use multiple .env files - this is supported by most if not all major dotenv libraries and Docker Compose.

You just need to load .env files in sequence (.env, then .env.local with local OVERRIDES). For example:

  1. Have all the config in .env, and have .env committed to version control. Including the EMPTY values for the service X.
  2. Have .env.local.dist file, with EMPTY values for the service X again (yes). Keep this as a reference of what NEEDS to be configured in local environment. Remember that local does not mean development - means local runtime, which might also be production.
  3. Have your local overrides in .env.local, and add .env.local to .gitignore.

This will ensure you only ever ignore bare minimum absolutely necessary local specific config, while also keeping auto-updating global sane defaults available for all users.

What about production?

Depends on your deployment infrastructure. Some elect to not even load .env in production, instead opting to use env directly, by means provided by the hosting infrastructure.

If you have to use dotenv files, and there is no other approach in place - use .env.local that is propagated to your runtime environment separately from your app and overrides all the secrets and specifics only in that environment.

You will still retain the benefits of “sane defaults” in devel and have your devel more closely aligned to other environments, such as production, where it makes sense to do so.

What I have found with many, many projects is that quite often large swath of app configs are exactly the same across all environments - with most common deviations being app secrets and credentials for services. It makes no sense to ship a complete config every time, where all you really need might be just a few overrides.

© Matīss Treinis 2022, all rights, some wrongs and most of the lefts reserved.
Unless explicitly stated otherwise, this article is licensed under a Creative Commons Attribution 4.0 International License.
All software code samples available in this page as part of the article content (code snippets and similar) are licensed under the terms and conditions of Apache License, version 2.0.