简体   繁体   English

节点 dotenv 不适用于 pm2

[英]node dotenv won't work with pm2

I have an application where locally (without pm2) all the environment variables in the .env file work just fine using dotenv .我有一个应用程序,其中.env文件中的所有环境变量在本地(没有 pm2)都可以正常使用dotenv

But on the server where I'm using pm2 to run the app, the environment variables remain undefined .但是在我使用pm2运行应用程序的服务器上,环境变量仍然是undefined

The pm2 commands I'm using to run the app on server are:我用来在服务器上运行应用程序的 pm2 命令是:

pm2 start myapp/app.js
pm2 startup
pm2 save

dotenv will read .env file located in the current directory. dotenv将读取位于当前目录中的.env文件。

When you call pm2 start myapp/app.js it won't search for myapp/.env .当您调用pm2 start myapp/app.js它不会搜索myapp/.env

.env // It will try to load this, which doesn't exist
myapp/
   app.js

So you have two solutions所以你有两个解决方案

use path option:使用path选项:

const path = require('path'); 
require('dotenv').config({ path: path.join(__dirname, '.env') });

Or call your script from inside myapp/或者从myapp/内部调用您的脚本

pm2 start app.js

A good pattern here is to remove dotenv from your code and "require" it on the command line.这里的一个好模式是从您的代码中删除 dotenv 并在命令行上“要求”它。 This makes your code nicely transportable between any environment (including cloud-based) - which is one of the main features of environment variables.这使您的代码可以在任何环境(包括基于云的)之间很好地传输 - 这是环境变量的主要功能之一。

Note: you will still need to install dotenv in your project via npm when running it on a server.注意:在服务器上运行时,您仍然需要通过 npm 在项目中安装 dotenv。

a) code up your .env file alongside your script (eg app.js) a) 将你的 .env 文件与你的脚本一起编码(例如 app.js)

b) to run your script without pm2: b) 在没有 pm2 的情况下运行您的脚本:

node -r dotenv/config app.js

c) in pm2.config.js: c) 在 pm2.config.js 中:

module.exports = {
  apps : [{
    name      : 'My Application',
    script    : 'app.js',
    node_args : '-r dotenv/config',
    ...
  }],
}

and then pm2 start pm2.config.js然后pm2 start pm2.config.js

note: the use of dotenv/config on the command line is one of the best practices recommended by dotenv themselves注意:在命令行中使用 dotenv/config 是 dotenv 自己推荐的最佳实践之一

edit 2021: for completeness - as my answer has got some ticks, I wanted to add a 4th option to the list: 2021 年编辑:为了完整起见 - 由于我的回答有一些问题,我想在列表中添加第四个选项:

d) combined pm2/env config d) 组合 pm2/env 配置

module.exports = { apps : [{
  name      : 'My Application',
  script    : 'app.js',
  env       : {
    PORT: 5010,
    DB_STRING: 'mongodb://localhost:27017',
    ...
  },
}]};

This will be useful if you are treating your pm2.config as environmental configuration and outside of git etc. It just negates the need for a separate .env, which may suit you.如果您将 pm2.config 视为环境配置并且在 git 等之外,这将非常有用。它只是不需要单独的 .env,这可能适合您。 It negates the need for dotenv completely as pm2 injects the env variables into your script's process它完全不需要 dotenv,因为 pm2 将 env 变量注入到脚本的进程中

you have kill you pm2 process first你先杀了你 pm2 进程

try尝试

pm2 kill

then restart pm2 using然后使用重新启动pm2

pm2 start app.js

I had the same problem but it wasnt explained clearly so here is the solution based on github user vmarchaud comment .我有同样的问题,但没有解释清楚,所以这里是基于 github 用户 vmarchaud comment的解决方案。 This also fixes the issue people had with @Andy Lorenz solution.这也解决了人们在使用 @Andy Lorenz 解决方案时遇到的问题。

In my case i wanted to create an ecosystem file for multiple apps but i was keep getting就我而言,我想为多个应用程序创建一个生态系统文件,但我一直在得到

Error: Cannot find module 'dotenv/config'

The solution was easy.解决方法很简单。 You have to declar cwd, aka the project folder where the dotenv/config will be read from.您必须声明 cwd,也就是将从中读取 dotenv/config 的项目文件夹。

module.exports = {
  apps: [{
    name: 'app1 name',
    script: 'app1.js',
    cwd: '/path/to/folder/',
    exec_mode: 'fork_mode',
    node_args: '-r dotenv/config',
  }, {
    name: 'app2 name',
    script: 'app2.js',
    cwd: '/path/to/folder/',
    instances: 'max',
    exec_mode: 'cluster',
    node_args: '-r dotenv/config',
  }],
};

You can parse .env using dotenv lib end set them manually in ecosystem.config.js您可以使用dotenv lib 解析.env并在ecosystem.config.js中手动设置它们

ecosystem.config.js:生态系统.config.js:

const { calcPath, getEnvVariables } = require('./helpers');

module.exports = {
  apps: [
    {
      script: calcPath('../dist/app.js'),
      name: 'dev',
      env: getEnvVariables(),
    },
  ],
};

helpers.js: helpers.js:

const path = require('path');
const dotenv = require('dotenv');
const fs = require('fs');

function calcPath(relativePath) {
  return path.join(__dirname, relativePath);
}

// this function will parce `.env` file but not set them to `process.env`
const getEnvVariables = () => {
  const envConfig = dotenv.parse(fs.readFileSync(calcPath('.env')));

  const requiredEnvVariables = ['MODE'];

  for (envVariable of requiredEnvVariables) {
    if (!envConfig[envVariable]) {
      throw new Error(`Environment variable "${envVariable}" is not set`);
    }
  }

  return envConfig;
};

None of this worked for me because I was using cluster mode.这些对我都不起作用,因为我使用的是集群模式。

I installed dotenv as dev dependency at the root (I was using yarn workspaces too).我在根目录下安装了 dotenv 作为开发依赖项(我也在使用纱线工作区)。

Then I did this:然后我这样做了:

require('dotenv').config({ path: 'path/to/your/.env' })

module.exports = {
    apps: [
        {
            name: 'app',
            script: 'server/dist/index.js',
            instances: 2,
            exec_mode: 'cluster',
            instance_var: 'APP_INSTANCE_SEQ',
            // listen_timeout: 10000,
            // restart_delay: 10000,
        }
    ]
}

I use a much simpler version of @Marcos answer:我使用了一个更简单版本的@Marcos 答案:

.env
app.js

for example we need to store token in .env file and pass it right to app.js : inside .env例如,我们需要将令牌存储在.env文件中并将其直接传递给app.js :在 .env 中

token=value

inside app.js:在 app.js 中:

require('dotenv').config();
console.log(process.env.token)

Also, don't forget.另外,不要忘记。 If you add .env file to .gitignore and then git pull you repo on VPS or smth, you need to copy .env file manually, otherwise your app won't work.如果您将 .env 文件添加到 .gitignore 然后git pull您在 VPS 或 smth 上的 repo,您​​需要手动复制 .env 文件,否则您的应用程序将无法运行。

And in some cases it's important in what area you are using your config, so make sure that NODE_ENV=production string is added to your .env file.在某些情况下,在您使用配置的区域很重要,因此请确保将NODE_ENV=production字符串添加到您的 .env 文件中。

After all you could use pm2 start app.js right from your app's folder.毕竟,您可以直接从应用程序的文件夹中使用pm2 start app.js

This was my project setup..这是我的项目设置..

/src/app.ts /src/app.ts

which than compiled into dist folder.然后编译到 dist 文件夹中。

/dist/app.js /dist/app.js

my .env file was outside dist folder so it wasn't accessible.我的 .env 文件在 dist 文件夹之外,因此无法访问。

this is the command i tried.这是我试过的命令。 pm2 start app.js --env=.env pm2 启动 app.js --env=.env

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM