dotenv files are great as a piece of developer ergonomics. And that's fine. I use them for that purpose all the time. I would not willingly consent to using them to manage environment variables in production. But I would also not willingly consent to doing it the way that's best for production during development.
I think that's fine. 12-factor is a set of guidelines about what you do in production. There's a whole universe of things that are smart ideas for development and bad ideas for production. Leaving debug symbols in your binaries, leaving ports for connecting a debugger open on your containers, etc.
It's interesting to me that your philosophy does sharply contradict with another popular notion which is that there is great benefit in unifying production and development environments. Curious what your take on that is.
There's an enormous difference between "I'm going to use a dev-friendly way to manage and swap out all the different configurations that I might want to plug into the app while I'm testing it, but still plug them in using the same mechanism", which is basically what you get with dotenv files, and, "I'm going to configure with environment variables in production and JSON files in development," which is another thing I often see people doing.
Ops person here. .env files at best should be injected into Developer environment by IDE/Editor. Many IDE/editors have this feature along with Docker. If that's not an option (Thanks JetBrains/Visual Studio), second thing is something like Python-dotenv where library loads .env file at startup, injects them into environment variables and rest of the code is configured to use environment variables. This behavior could even be environment variable controlled and should not error if no .env file is present.
I think that's fine. 12-factor is a set of guidelines about what you do in production. There's a whole universe of things that are smart ideas for development and bad ideas for production. Leaving debug symbols in your binaries, leaving ports for connecting a debugger open on your containers, etc.