6

I have some .env files for my backend application and the usual recommendation is to put all .env files in gitignore to not share it in the repo and use something like Github Secrets to store the .env files.

That sounds a good thing to do, but if I have a private repo, where only people that should know the .env files have access to it, should I still hide the .env files? Or is it ok to commit these files?

Every time someones joins the team, I need to shared these .env files because it's not commited in the repo, which is something I don't like.

So for a private repo, it should be totally ok to commit the .env files right?

1
  • 1
    The only way you can be somewhat OK with that is if the private repo were not hosted by a public service. IOW, only on your internal hardware that does not have access to the internet. Any public facing service can be compromised. The question is how sensitive the information you need to protect is. Jan 4 at 19:41
6

Every time someones joins the team, I need to shared these .env files because it's not commited in the repo, which is something I don't like.

There is a simple solution for this: gitignore .env files, but also have a file like .env_default which you keep under source control, with some reasonable default settings (as long as those are not confidential or risky to publish). When someone needs a .env file the first time, they have simply to make a copy of .env_default as .env and adapt the file to their environment.

The .env_default file may also keep some necessary environment variables unset (and hence make the program display an error message when someone forgets to set them). That way, users are forced to look into the script and edit it before running the system. It could also provide some comments with some hints how the variables should be set.

That way, your team can still exchange the important content of those .env files directly by source control, without using another channel. You get also the benefits of having a history for your .env_default files. Note this also works when your repo is not private.

1
  • Unsure if a convention has already crystallized on this, but I've encountered *.dist at several companies as the name for distributed files. In this case, .env.dist.
    – Flater
    Jan 5 at 13:53
5

I'd .gitignore those files.

There's the idea that configuration is not part of the code – it describes the environment that a software is being deployed in. This view is promoted e.g. by The Twelve-Factor App, a guide to building SaaS by Heroku.

Because the deployment environments differ, it makes no sense to check in environment-specific configuration to your software's version control. Instead, the deployment environment should provide the necessary configuration itself, e.g. via environment variables. Using .env files is just a convenient way for managing environment variables with some frameworks.

But some things do not differ between deployment environments. Those things are code and should be checked in. In particular, I would expect a software to run in a sane default configuration if there are no environment variables, with the only required parameters being connections to other services (e.g. a database connection string).

Story time: I worked at a place where we developed some enterprise software with various services. To my delight, the tests were easy to run. And I ran them often. Until one day, a senior engineer came to my desk and asked me to stop using his database for my tests! What had happened? The engineer had checked in his configuration file and added a connection string to a test database he had running somewhere. I didn't know that, so I was overwriting his data all the time. Not good.

Of course I immediately started my own database instance and modified the configuration file, but for the rest of my time there I had to remember to never commit my modifications to that file since it would overwrite my team members' configuration…

From the 12-factor perspective, the problem was that a configuration was checked in that was specific to one deployment environment, but was not provided by the deployment environment. If there hadn't been a default configuration file, the software would have loudly complained that it didn't have a database connection so I would have known to set one up.

Even better would have been if the test environment had been completely automated so that I could spin up a test deployment and it would configure itself. Back then, we couldn't use Docker. But now, it's super easy to define a reproducible deployment environment. I often write docker-compose files that spin up the necessary containers and connect them as appropriate. In the definition of those services, I can also define environment variables that are injected into the containers. Since these env vars only refer to services within this reproducible test environment, that is safe to do. But the important point is that the environment (as defined in the docker-compose file) provides its configuration to the software.

You don't have to use docker-compose or similar technologies if they don't make sense. You don't have to build a 12-factor app. But I would invite you to re-consider the role of this .env file:

  • What is in this environment that is boilerplate? Why isn't it a default of your software?
  • Why is it necessary to provide configuration in order to get a test or development environment? Why can't this be scripted or automated in any way?

Additionally, consider security implications. It is fine to disagree with this answer and to commit configuration that is specific to a deployment environment. However, Git is blockchain-like: an append-only data structure that prevents later modifications. The most you can do is to record an alternate history and then forget about the original history. So if you commit a secret once, it remains in the Git repository forever, unless and until you learn about history rewriting with git filter-branch and put up with the wonderful world of merge conflicts that are likely to result. A world of headaches awaits you. It is much better to never commit secrets in the first place. This also reduces the impact of accidental leaks, like accidentally putting a .git folder under the webroot of a web server (been there, done that). For managing secrets in a team, use a password manager.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.