Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how can I handle multiple environments? #220

Closed
muhammadnasr opened this issue Aug 6, 2017 · 16 comments
Closed

how can I handle multiple environments? #220

muhammadnasr opened this issue Aug 6, 2017 · 16 comments

Comments

@muhammadnasr
Copy link

Thanks for the great lib.
You recommend against having multiple env files
How can I handle having production, staging and development environments and each one has its own API keys and passwords without having multiple files?

@maxbeatty
Copy link
Contributor

Do:

$ cd my-project
$ touch .env
$ ssh prod
$ cd my-project
$ touch .env
$ exit
$ ssh qa
$ cd my-project
$ touch .env
$ exit

Do Not:

$ git add .env .env.production .env.qa

@gkatsanos
Copy link

gkatsanos commented Nov 4, 2017

I am sorry but I dont understand how this can be automated with a git-based deployment for example.
I have a .env which has the URI of my Mongo Database. Which is different between local and production (of course).

How do I handle that?
Do I have to manually FTP or SSH into the environment and make the file myself?

@maxbeatty
Copy link
Contributor

Yes, you would prepare your .env file on your remote host using FTP or SSH (maybe at the same time you’re setting up git). Then during deployment after you have pushed your new release via git and before you start your process, you could copy or symlink the .env file in place. If your remote host is something like Heroku, you do not need a .env file since the environment will already be populated with your configuration.

@gkatsanos
Copy link

gkatsanos commented Nov 5, 2017 via email

@schickling
Copy link

I think there is no general right or wrong here. How you're handling environment variables is highly dependent on some of the following things:

  • Deployment setup
    • Manually deploying via SSH or FTP (increasingly irrelevant imo)
    • Automatic deployments via CI/CD
  • Deployment target
    • Using a service (Heroku, now)
    • Container setup (Kubernetes, ECS)
  • Security requirements (you might also want to consider something like Vault)
  • Development phase of your application (are you just building a prototype or a large-scale production app)

@gkatsanos
Copy link

gkatsanos commented Dec 2, 2017

I figured it out.
Most hosted environments (all of them?) provide a web UI that allows you to add the needed environment variables permanently and securely. In some it's a little trickier (for example Google Cloud Engine + Kubernetes) especially when you need to add a Mongo URI but it's just a question of finding the right value.
I guess the above could be mentioned in your Readmes? - dotenv and dotenv-safe are essentially tools for local environments and not prod deployments. (which is pretty obvious once you realize there's no physical way to put secret passwords and hashes in a physical file)

@kerimdzhanov
Copy link

Hi there!

We are using the "multiple env files" model in many projects for a years and feeling very comfortable with it. I know that dotenv doesn't recommend to commit .env file and have a multiple .env* files in your projects, but we have a slightly different approach to manage .env* files (it's described in my README.md).

Please take a look at https://github.com/kerimdzhanov/dotenv-flow and star the repo if you're interested in. Any feedback is very appreciated, feel free to ask questions, create issues and submit your PR's.

P.S.
@motdotla, I would be very glad if you can add this lib to your Go well with dotenv section.

@jhalborg
Copy link

jhalborg commented Aug 15, 2018

As a PaaS user (Zeit Now in my case), I think the only approach that makes sense to me is what @gkatsanos proposes - to use the .env file for local development, and use the PaaS provided method for saving environment variables for each deployment, seeing as you won't SSH the file in AFAIK. This would also support deployment from build servers like Bitbucket Pipelines without having to commit the .env files to the repo.

I don't see any other way to keep .env files out of git and still use git based deployments to PaaS services (like Zeit and Heroku), am I missing something? I'd much prefer having multiple .env files (i.e. .env.prod, without them sharing values), but I don't see how I can use that approach while using a gitbased deployment?

@erisanolasheni
Copy link

You can run multiple environments on node with custom-env, it's a dotenv dependent >> npm install custom-env Docs: https://www.npmjs.com/package/custom-env

@gsanikidze
Copy link

There is a solution - #272 (comment)

@morgler
Copy link

morgler commented Mar 17, 2019

I understand the single .env file policy for regular web apps. But how do I do it with a static frontend SPA, which I build for production on my LOCAL machine? There is no way of inserting ENV variables dynamically for a static website, so I must store them on my local machine. In essence I need two .env files: .env.development and .env.production. Or am I totally misunderstanding something?

@maxbeatty
Copy link
Contributor

For frontend configuration, you should use something like webpack's environment variables. If you're using another bundler/compiler, I'm sure there's something similar. You might also find inspiration from create-react-app.

@yinrong
Copy link

yinrong commented Mar 26, 2019

is this a good solution?
https://github.com/yinrong/menv

@als9xd
Copy link

als9xd commented Apr 14, 2019

Here is what I am doing.

import * as fs from 'fs';
import * as path from 'path';
import * as dotenv from 'dotenv';

function getEnvs(envs: string[]) {
    const cwd = process.cwd();
    return [
        '.env.local',
        ...envs.map(env => `.env.${env}.local`),
        '.env',
        ...envs.map(env => `.env.${env}`),
    ]
        .map(fileName => path.resolve(cwd, fileName))
        .filter(filePath => fs.existsSync(filePath))
        .reduce((settings, path) => {
            const foundSettings = dotenv.config({ path });
            if (foundSettings.error) throw foundSettings.error;
            return { ...settings, ...foundSettings.parsed };
        }, {})
}

getEnvs([
    'dev',
    'staging',
    'prod',
]);

Which loads them in this order:

 [ 'E:\\my-project\\.env.dev.local',
  'E:\\my-project\\.env.staging.local',
  'E:\\my-project\\.env.prod.local',
  'E:\\my-project\\.env.local',
  'E:\\my-project\\.env.dev',
  'E:\\my-project\\.env.staging',
  'E:\\my-project\\.env.prod',
  'E:\\my-project\\.env' ]

@lucaspiressimao
Copy link

Here Ability to require/include other .env files ? it is a good solution...

@motdotla
Copy link
Owner

We recommend using a .env.vault for this today. You can couple it with https://github.com/dotenv-org/dotenv-vault#local-build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests