Beanstalk: Node.js deployment - node-gyp fails due to permission denied

node.jsAmazon Elastic-Beanstalk

node.js Problem Overview


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.

node.js Solutions


Solution 1 - node.js

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

Solution 2 - node.js

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

Solution 3 - node.js

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

Solution 4 - node.js

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

Solution 5 - node.js

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

Solution 6 - node.js

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$ 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJakub HolýView Question on Stackoverflow
Solution 1 - node.jsJakub HolýView Answer on Stackoverflow
Solution 2 - node.jsMarzView Answer on Stackoverflow
Solution 3 - node.jsmalik masisView Answer on Stackoverflow
Solution 4 - node.jsbuhgityView Answer on Stackoverflow
Solution 5 - node.jsBiraView Answer on Stackoverflow
Solution 6 - node.jsJeremy JonesView Answer on Stackoverflow