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"
}
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.
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.
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
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.