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:
- Have all the config in
.env
, and have.env
committed to version control. Including the EMPTY values for the service X. - 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. - 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.