Recently I run into a problem during initial deployment to one of our EB stacks (Build: Node.js 12 running on 64bit Amazon Linux 2/5.2.4). I found something like this in the logs and was completely confused; why deployer doesn't have enough permissions?

Failed to execute '/opt/elasticbeanstalk/node-install/node-v12.19.0-linux-x64/bin/node /opt/elasticbeanstalk/node-install/node-v12.19.0-linux-x64/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/var/app/staging/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node --module_name=bcrypt_lib --module_path=/var/app/staging/node_modules/bcrypt/lib/binding/napi-v3 --napi_version=7 --node_abi_napi=napi --napi_build_version=3 --node_napi_label=napi-v3' (1)

2020/11/20 05:00:32.248204 [ERROR] An error occurred during execution of command [app-deploy] - [Use NPM to install dependencies]. Stop running the command. Error: Command /bin/sh -c npm --production install failed with error exit status 1. Stderr:Unable to save binary /var/app/staging/node_modules/node-sass/vendor/linux-x64-72 : Error: EACCES: permission denied, mkdir '/var/app/staging/node_modules/node-sass/vendor'
    at Object.mkdirSync (fs.js:921:3)
    at sync (/var/app/staging/node_modules/mkdirp/index.js:72:13)
    at Function.sync (/var/app/staging/node_modules/mkdirp/index.js:78:24)
    at checkAndDownloadBinary (/var/app/staging/node_modules/node-sass/scripts/install.js:114:11)
    at Object.<anonymous> (/var/app/staging/node_modules/node-sass/scripts/install.js:157:1)
    at Module._compile (internal/modules/cjs/loader.js:1015:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
    at Module.load (internal/modules/cjs/loader.js:879:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12) {
  errno: -13,
  syscall: 'mkdir',
  code: 'EACCES',
  path: '/var/app/staging/node_modules/node-sass/vendor'
}

I spent several days trying to figure out what is going on until I realized that all node modules are installed using root user, and some are installed with ec2-user, which doest have permissions to mkdir.

Occurs Npm has a build-in solution - you need to enable unsafe-permissions:

Set to true to suppress the UID/GID switching when running package scripts. If set explicitly to false, then installing as a non-root user will fail.

To do that, run:

touch .npmrc
echo "unsafe-perm=true" > ~/.npmrc

Or if you already have .npmrc, add unsafe-perm=true there.

I hope this will save someone some time!