phpdotenv icon indicating copy to clipboard operation
phpdotenv copied to clipboard

One .env to rule them all

Open antonioribeiro opened this issue 4 years ago • 12 comments

Managing several '.env' files plus a '.env.example' is sometimes complicated, and frequently we get some of those files out of sync.

So, it could be a nice feature to be able to use a single .env file for all environments, by just hinting environments like:

DB_CONNECTION=pgsql // default, not found, or simply the same on all environments

DB_HOST.local=127.0.0.1
DB_HOST.testing=postgres
DB_HOST.staging=10.0.0.2
DB_HOST.production=172.17.0.101

And, of course, way of loading for loading the current environment:

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load('production');

antonioribeiro avatar Aug 21 '20 09:08 antonioribeiro

Thanks for getting in touch. I don't see the use case here, since your production secrets should never be committed to the repo? Why would you need to have production and local side by side?

GrahamCampbell avatar Aug 21 '20 10:08 GrahamCampbell

Hello @GrahamCampbell !

Think about having 4 sites on Forge, plus one local .env file, and, yes, we are safe, so they are not commited to the repository.

Every time I make a change to my local .env file, I have to make the same change to the .env.example (not in question here!) and then go to 4 Forge sites and edit one by one, making the same changes, just changing those 5 new keys I just added, sometimes having to find the right place on each file where to put those keys. Some data will be the same, some will be different because they are private keys, but I still have to do all the work 4 times, and as a human repeating the same job, I will miss something, or forget one, or just be lazy and let the thing to be done later, and it will be missed.

Having a single .env file would allow me to

  • Go to one of my Forge environments
  • Copy the contents, except for the APP_ENV, of course
  • Add those 5 new keys for all environments
  • Then just paste that file on my 4 Forge sites.

It's much simpler, faster, easier, less prone to (repetition) errors, and it also gives me visibility on all environments at the same time so it's also informative.

antonioribeiro avatar Aug 21 '20 10:08 antonioribeiro

It seems a limitation.

The basic parser for INI can read this

[FAILOVER]
NODE[]=8.8.8.8:80,443
NODE[]=1.1.1.1:80,443

[HEALTHCHECK]
INTERVAL=15000
TIMEOUT=3
RETRY=3

with parse_ini_file(".env", true, INI_SCANNER_TYPED);

So I can have grouping & arrays with complete happiness.

But we can't do the same with dot-env. Does it?

It's interesting to develop a dot notation feature.

So we can retrieve with staging.db_host (or db_host.staging as said).

+1 for dot notation 👍

ps. It sounds like the config helper of Laravel as such.

hakuno avatar Sep 09 '20 03:09 hakuno

I am going to defer the decision of whether this is wanted to @taylorotwell and @jbrooksuk, if your use case is purely Forge.

GrahamCampbell avatar Sep 16 '20 21:09 GrahamCampbell

This seems unlikely to be a correct use. @antonioribeiro

selcukcukur avatar Sep 23 '20 14:09 selcukcukur

@GrahamCampbell , I keep hearing this, but the "use case" argument for denying something is not the best for a community as big as PHP or Laravel, because, the bigger the community the nearest from infinity "use cases" can get.

My use case is not your use case and will probably not be from thousands of other developers. My use case can also change according to the client I'm working for or the infrastructure I'm deploying. Have you tried to update a bunch of .env keys on an Azure App Service? It's a nightmare! Our last app is being deployed to it, we have dozens of keys, and the only way to do it in bulk is to update a JSON file like this:

image

This one has 640 lines * 3 environments = 1920 lines, I broke this JSON several times, I also pasted the wrong keys to the wrong environment, because, yes, I'm not good doing boring repeating tasks.

So maybe the use case is reducing repetition and human errors?

Otherwise you have to click to edit one-by-one. But they are super secure, so it would not be a big security problem to have the keys for all 3 clusters in a single JSON file. The amount of errors I make would drop considerably, because, yes, I'm not good doing boring repeating tasks.

The real use case here is namespacing the .env file.

Forge was just an example, and Forge, as far as I can tell is just a server provisioning boxes supporting natively only a few services, but the use case is any server, any box, any service deploying Laravel apps, on AWS, Azure, Google Cloud, Docker, Kubernettes, Linode, Vultr, Scaleway, DigitalOcean, OVH, Alibaba... managed by Forge or anything else, and believe me, there are a lot of other dashboards doing the same out there, and many of those services have their own deployment and app management systems too.

antonioribeiro avatar Sep 26 '20 17:09 antonioribeiro

@antonioribeiro I guess you need to overcome this limitation and look for some DevOps approach. I'm unsure how much the staff want to increment one new feature like that. Unless you've a ready PR for review.

Ps. Actually, those settings are related to many environments (in your use case closely). If you set all environments rather than current one, so it becomes a configuration instead of set of environment variables.

hakuno avatar Sep 29 '20 19:09 hakuno

PHPDotenv already natively supports loading more than one file. Why can't you just load a base file and then a file specific to the environment you have?

GrahamCampbell avatar Sep 29 '20 20:09 GrahamCampbell

@antonioribeiro - Could you possibly use something like array_merge to do what you want? Load your default file, then load another for a different environment, and merge the arrays while overwriting keys (where necessary)? It may be a stop-gap measure if there isn't going to be official support for it.

XaeroDegreaz avatar Nov 11 '20 07:11 XaeroDegreaz

@antonioribeiro - I think GNU Make can help you solve the problem.

Makefile:

.env: .env.example
    @./scripts/update_env

then just:

$ make

So, you can keep your .env file updated.

dobryak avatar Nov 28 '20 23:11 dobryak

Can they consider using TOML for the .env files? The .env files, especially of Laravel, would be so much cleaner!

nahiyan avatar Apr 06 '21 08:04 nahiyan

Sounds more like you don't want to use .env files for things. Also, not really understanding how your wouldn't need to edit the values in all the places if a file was changed or a field added.

frob avatar Dec 10 '21 07:12 frob

I'm going to close this out for now as out of scope of what the package was intended to do.

GrahamCampbell avatar Oct 16 '22 01:10 GrahamCampbell