How does AWS Beanstalk use NPM when deploying a No

2019-04-03 23:43发布

问题:

I'm curious about the overall workflow of an AWS Beanstalk deployment. I'm assuming it runs npm at some point to get the packages installed on the server(s). But I was just wondering if AWS Beanstalk uses the latest command of 'npm install --production' to install packages. Currently I have a packages.json file as shown below and would like to insure if possible that only the dependencies are being installed and not the devDependencies.

"dependencies": {
  "express": "3.4.4",
  "jade": "*",
  "restify": "~2.6.0",
  "assert": "~1.0.0",
  "orchestrate": "0.0.2",
  "chance": "~0.5.3"
}, 
"devDependencies": {
  "mocha": "~1.15.1"
}

回答1:

Currently the Elastic Beanstalk environment runs npm install without the --production flag. This happens on the instance at /opt/elasticbeanstalk/containerfiles/ebnode.py before any env customizations supplied by the developer (i.e., environment option settings) are exported, which means setting NODE_ENV=production in the EB Environment's configuration also does not prevent devDependencies from being processed.



回答2:

You can get AWS Elastic Beanstalk to run npm install in production mode if you set the environment variable NPM_CONFIG_PRODUCTION=true. You can do this through the Elastic Beanstalk web console.

Alternatively, save the following text to any file with suffix .config inside a directory called .ebextensions in the project root and you can achieve the same thing without having to set them every time in the web console:

option_settings:

  - option_name: NPM_CONFIG_PRODUCTION
    value: true

Note: make sure you're using spaces, not tabs, as it's YAML format.

I found that the time to update new node.js code in a t1.micro environment went down from about 5 minutes to 90 seconds, now that it wasn't installing all the devDependencies such as grunt, karma, mocha, etc.



回答3:

In the new versions of Elastic Beanstalk Node's stacks, the configuration has changed, as pointed by @etreworgy's comment.

You can check the current behavior, by running inside an EC2 instance:

cat /opt/elasticbeanstalk/containerfiles/ebnode.py | grep -A 5 PRODUCTION

It returns, as of today:

        if 'NPM_USE_PRODUCTION' not in npm_env:
            npm_env['NPM_USE_PRODUCTION'] = 'true'

        if npm_env['NPM_USE_PRODUCTION'] == 'true':
            print 'Running npm with --production flag'
            check_call([npm_path, '--production', 'install'], cwd=app_path, env=npm_env)
            check_call([npm_path, '--production', 'rebuild'], cwd=app_path, env=npm_env)
        else:
            print 'Running npm without --production flag'

So, currently, it uses the npm install --production by default.

For those ones that want to disable it (as I was when I went to this answer), you have to create a anything.config inside an .ebextensions folder at your project's root folder (where anything means really anything; node, npm, whatever you want), with the content:

option_settings:
    - namespace: aws:elasticbeanstalk:application:environment
      option_name: NPM_USE_PRODUCTION
      value: false


回答4:

An additional option is to use npm-shrinkwrap, which has the additional benefit of letting you lock your dependencies at the same time.

AWS Elastic Beanstalk suggests it here.