79

Deployment of a Node.js application (Node 6, npm 5) to Beanstalk fails with:

gyp ERR! stack Error: EACCES: permission denied, mkdir '/tmp/deployment/application/node_modules/heapdump/build'

though the error is not package-specific, any node-gyp call fails.

The ERROR event in the AWS Console reads:

[Instance: i-12345] Command failed on instance. Return code: 1 Output: (TRUNCATED).../opt/elasticbeanstalk/containerfiles/ebnode.py", line 180, in npm_install raise e subprocess.CalledProcessError: Command '['/opt/elasticbeanstalk/node-install/node-v6.10.0-linux-x64/bin/npm', '--production', 'install']' returned non-zero exit status 1. Hook /opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh failed. For more detail, check /var/log/eb-activity.log using console or EB CLI.

and eb-activity.log contained the aforementioned npm error.

The application was deployed manually by uploading a .zip file that did not include node_modules. I.e. it was not deployed via the eb command-line tool.

Jakub Holý
  • 5,295
  • 2
  • 26
  • 31

6 Answers6

216

Solution

The solution is to add the file .npmrc to the application with the content:

# Force npm to run node-gyp also as root, preventing permission denied errors in AWS with npm@5
unsafe-perm=true

(Or configuring npm so in any other way. (Though setting npm_config_unsafe_perm=true in /opt/elasticbeanstalk/env.vars did not work for me.)

Explanation

npm install is run by the root user but the node-gyp process it triggers for some packages is run by the default user ec2-user. This user lacks access to the /tmp/deployment/application/node_modules/ directory created by the npm install run and owned by root. (And it likely also lacks access to /tmp/.npm and /tmp/.config created by the same.) By enabling unsafe-perm we force npm to run node-gyp also as root, avoiding the problem.

(Personally I would prefer to run all as ec2-user rather than root but I guess that would be more involved :-))

Credits

unreal0 has pointed me to the solution

Related questions

Jakub Holý
  • 5,295
  • 2
  • 26
  • 31
  • 16
    Thank you! `unsafe-perm=true` in `.npmrc` solved the problem for me. – Lauri Lehmijoki Nov 07 '17 at 03:18
  • 2
    Me too. Had the same error when trying to install Puppeteer using Node 8.4.0, npm 5.3.0. Thanks! – clay Dec 01 '17 at 19:38
  • 2
    Great solution. This beats the various fragile .ebextensions based workarounds out there, hands down! – pscl Jan 29 '18 at 20:32
  • Thanks. Finally I find a solution that works. I have been spending days and had no idea why I couldnt deploy my app. – Tenz Mar 07 '18 at 18:21
  • Good solution and explanation. You saved my times. Thank you. – Jeff Gu Kang Jun 20 '18 at 12:40
  • Man, all my admiration. I was not able to deploy to Elastic Beanstalk until I set unsafe-perm=true in .nprmc (created at the working directory of the app). Thank you so much. – hjbello Oct 18 '18 at 12:32
  • just what i needed – Ricky Brown Jan 09 '19 at 23:37
  • I can't believe how this problem has been painting the whole street with my head. You have saved me from this. For some of you that had "command not found" issue using `$ sudo npm install` on Ubuntu, try to log in as root user using `$ sudo -s` and run your normal `$ npm install` but, don't forget to add `.npmrc` to the root folder of your node project. – Cocest Feb 19 '19 at 11:19
  • Using Ubuntu, I created .npmrc in the home folder, e.g.: nano ~/.npmrc – Online Sid Mar 05 '19 at 09:30
  • Saved the day! app is finally deployed – tito.300 Mar 30 '19 at 00:08
  • You are great. The worst thing about beanstalk is that the docs are so incomplete so finding a solution changing the permissions... I would rather deploy multiple ec2 instances instead. your solution is the best in my opinion, even though, as you said it feels a little bad to run it as root. I would expect AWS to handle this kind of stuff if EBS is actually a platform but until then good luck to us. – Maayao Jun 03 '19 at 13:48
  • 5
    For those having a git repo connected to your application: Do not forget to commit the file. As from the [docs](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb3-deploy.html) "If git is installed, EB CLI uses the git archive command to create a .zip file from the contents of the most recent git commit command." - If you dont commit, the file wont exist in your next "eb deploy" – Dusty48 Jun 29 '19 at 07:15
  • 5
    This solution did not work for me. It's still failing – Erick Maynard Aug 11 '19 at 07:31
  • @Dusty48 Your comment was really helpful. – necixy Mar 18 '20 at 06:38
  • where i put .npmrc on the project or server? – Arif Fathurrohman Jun 25 '20 at 14:34
  • You can use `--unsafe-perm` parameter when you give installation command. – samet Jul 14 '20 at 09:03
  • thank you, it worked for me. – bongtoi Feb 25 '21 at 10:24
  • Thank you for this! I had to add `npm_config_unsafe_perm=true` as an EBS environment variable to get this working for me. – meverson May 06 '21 at 20:39
6

My team and I were able to get this working on an Amazon NodeJS machine by overriding some of the configuration in the script that initializes the service. This essentially overwrites the included aws node run configuration with the exact same script and a couple of extra commands. This is a file you would place under .ebextensions

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash
      #==============================================================================
      # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
      #
      # Licensed under the Amazon Software License (the "License"). You may not use
      # this file except in compliance with the License. A copy of the License is
      # located at
      #
      #       http://aws.amazon.com/asl/
      #
      # or in the "license" file accompanying this file. This file is distributed on
      # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or
      # implied. See the License for the specific language governing permissions
      # and limitations under the License.
      #==============================================================================

      chmod 777 -R /tmp
      set -xe

      sudo /opt/elasticbeanstalk/containerfiles/ebnode.py --action npm-install
Marz
  • 381
  • 5
  • 10
2

i fixed with aws configuration on instance. t2.micro => t2.small or larger one. enter link description here

malik masis
  • 327
  • 2
  • 8
2

In my case, solved by setting "unsafe-perm=true" in "~/.npmrc"

buhgity
  • 21
  • 3
1

We need to do 2 things here.

First one: If you do not already have a .ebextensions folder in the root of your project, create it. Then create a file in .ebextensions named 01_fix_permissions.config.

Then secondly Enable PROXY set -xe and /opt/elasticbeanstalk/bin/healthd-track-pidfile --proxy nginx

files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/49_change_permissions.sh":
mode: "000755"
owner: root
group: root
content: |
  #!/usr/bin/env bash
  sudo chown -R ec2-user:ec2-user tmp/
  set -xe
  /opt/elasticbeanstalk/bin/healthd-track-pidfile --proxy nginx
Bira
  • 2,485
  • 1
  • 20
  • 35
0

I needed to create & commit both a .npmrc file and a .ebextensions/01-permissions.config file to resolve this:

www$ cat .npmrc
# Force npm to run node-gyp also as root, preventing permission denied errors in AWS with npm@5
unsafe-perm=true
www$ cat .ebextensions/01-permissions.config 
files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/49_change_permissions.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      sudo chown -R ec2-user:ec2-user tmp/
www$ 

Jeremy Jones
  • 2,275
  • 12
  • 22