24

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"
}
Adron
  • 1,698
  • 3
  • 19
  • 40

4 Answers4

24

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.

rgareth
  • 3,377
  • 5
  • 23
  • 35
  • 13
    In the most recent Elastic Beanstalk solution stack (64bit Amazon Linux 2014.03 v1.0.4 running Node.js) the ebnode.py script references a `NPM_USE_PRODUCTION` variable that defaults to 'true'. Setting this to 'false' in your .config files will result in `npm install` being run without the `--production` flag. I found no reference to a `NPM_CONFIG_PRODUCTION` variable, though it's possible it gets used elsewhere to set `NPM_USE_PRODUCTION`. Neither variable seems to be mentioned in any of Amazon's configuration documentation. – etreworgy Jul 25 '14 at 22:52
  • 1
    Will this run the `postinstall`? – Shamoon Apr 22 '15 at 14:51
  • 1
    Apparently doesn't run `postinstall`, but it will run `prestart`. How have they managed to make npm usage so difficult? – Joshua Breeden Apr 25 '17 at 03:33
  • 1
    Your answer is almost complete though this days as for 2021 you need to use the env var called NPM_USE_PRODUCTION and not NPM_CONFIG_PRODUCTION. – Kashkashio Feb 10 '21 at 13:04
17

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
Edmundo Santos
  • 8,006
  • 3
  • 28
  • 38
  • Thank you very much, your answer is so easy but solved the same problem for me. – Yarovoy Sep 11 '18 at 15:56
  • 1
    `/opt/elasticbeanstalk/containerfiles/ebnode.py` there is no such directory or file on the instance. Can someone say where can I see this file? – papabiceps Jul 06 '21 at 23:42
  • I wrote this 4 years ago, I wouldn't be surprised if they changed it. I no longer use EBS so I can't confirm, but in any case the rest of the answer is still valid, the --production flag is used by default and you can disable it using NPM_USE_PRODUCTION as seen here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/nodejs-platform-dependencies.html – Edmundo Santos Jul 07 '21 at 09:24
5

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.

Evan Brown
  • 382
  • 2
  • 2
  • Thanks for the answer. Definitely good if this were added as a feature. I realize too that the Node.js team kind of snuck that in there on us all. ;) – Adron Dec 13 '13 at 00:57
  • 11
    This is not a correct answer (at least, today). The way to influence `npm install` is via variable `NPM_CONFIG_PRODUCTION` and not `NODE_ENV`. Elastic Beanstalk does support this, as I have noted in my own answer below. – rgareth May 08 '14 at 15:33
  • 1
    update feb 2020: "By default, Elastic Beanstalk installs dependencies in production mode (npm install --production). If you want to install development dependencies on your environment instances, set the NPM_USE_PRODUCTION environment property to false." – Ryan Feb 10 '20 at 20:44
  • 1
    `/opt/elasticbeanstalk/containerfiles/ebnode.py` there is no such directory or file on the instance. Can someone tell where can I see this? – papabiceps Jul 06 '21 at 23:41
  • @papabiceps I think the /opt/elasticbeanstalk/containerfiles/ebnode.py file doesn't exist anymore in AWS Linux 2 and the functionality has moved somewhere else. Did you ever figure out the new file that this runs from? I'm trying to figure that out now https://stackoverflow.com/questions/72466543/stop-ebs-linux-2-node-js-from-trying-to-do-npm-install – Alex von Brandenfels Jun 01 '22 at 20:00
1

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.

Stevi Deter
  • 1,653
  • 12
  • 16
  • 1
    The referenced documentation also states that npm-shrinkwrap will speed up deployments as npm install will only need to executed once. – dhollenbeck Sep 08 '16 at 13:33