NPM Error: EACCES: permission denied

Issue #16846 open
Philip Hodder
staff created an issue

When running NPM on Alpine-based Docker images as root user, the following error message is returned with a stack trace:

Error: EACCES: permission denied

Am I affected by this?

  1. To see if you are running as the root user, you can run: $ whoami
  2. To see if you are running an Alpine-based Docker image, you can run: $ cat /etc/os-release

Workaround

Please ensure you have cleared your node caches in Pipelines when trying these solutions.

  1. You can configure your pipeline to run as another user as this issue only occurs when you are running as the 'root' user.
  2. If you need to run as the root user, you will need to use a non-Alpine-based Docker image.
    • For example, if you are using the node:8 Docker image, then instead you could use node:8-jessie.

Why is this happening now?

On July 31st 2018, the Pipelines team upgraded AWS instance types to keep up with our scaling and performance requirements. However, this exposed a downstream bug which affects the current versions of Alpine. As a result of this bug, certain NPM builds have started failing. Note: We will update this ticket as we get more information.

We have added our own workaround where possible, which have covered the majority of NPM build failures, however this particular issue unfortunate requires manual intervention.

Comments (12)

  1. Nathan Burrell staff

    This error is caused by an issue with node based alpine image.

    The issue stems from an incompatibility with alpines c runtime libmusl which appears to not be returning the correct values from certain system calls when running on AWSs new hypervisor nitro which m5 instances run on.

    We have a workaround in place to alleviate most of the issues, but there are some features of node on alpine that the workaround doesnt/cant cover, and the workaround suggested above applies to them.

    We have a support case raised with AWS who are in contact with the alpine/libmusl maintainers, to find a solution to this issue :)

    Kind Regards, Nathan Burrell

  2. Tom Klingenberg

    @Nathan Burrell : Do you have reference to the upstream issue (at AWS)?

    My findings so far were: According to the npm script docs "nobody" is the default user as in the docker container the user is "root". In such a case you can use the --unsafe switch with the npm install command.

    So from the npm docs the behavior there currently is reported does actually looks like behaving correctly and not a bug. Just saying.

    Take care w/ using root inside docker containers, root is a shared resource.

  3. Nathan Burrell staff

    Hi Tom,

    We currently have a support case raised with AWS (which is unfortunately private) where they have acknowledged a change in behaviour between m4s and m5s caused by libmusl (they are apparently in contact with the libmusl team organising a fix).

    As for any public issues describing it I linked them in my above post but ill link them again here for your perusal:

    This one describes the change in behaviour and has a reproduciple test so you can see the change in behaviour: https://github.com/npm/npm/issues/20861

    This one has some more info about one of the issues with libmusl running m5s (and thus nitro). https://github.com/nodejs/docker-node/issues/813

    As for the behaviour you are correct in which user it is returning the bug is (as described on the AWS support case).

    But for some reason on M5 instances, the function returns the username as the user id, note the [ 'nobody', 0 ] in the error below
    
    $ docker container  run  -it node:8-alpine /bin/sh -c 'npm -g'
    Error: could not get uid/gid
    [ 'nobody', 0 ]
    
        at /usr/local/lib/node_modules/npm/node_modules/uid-number/uid-number.js:37:16
        at ChildProcess.exithandler (child_process.js:282:5)
        at emitTwo (events.js:126:13)
        at ChildProcess.emit (events.js:214:7)
        at maybeClose (internal/child_process.js:925:16)
        at Socket.stream.socket.on (internal/child_process.js:346:11)
        at emitOne (events.js:116:13)
        at Socket.emit (events.js:211:7)
        at Pipe._handle.close [as _onclose] (net.js:557:12)
    TypeError: Cannot read property 'get' of undefined
        at errorHandler (/usr/local/lib/node_modules/npm/lib/utils/error-handler.js:205:18)
        at /usr/local/lib/node_modules/npm/bin/npm-cli.js:83:20
        at cb (/usr/local/lib/node_modules/npm/lib/npm.js:224:22)
        at /usr/local/lib/node_modules/npm/lib/npm.js:262:24
        at /usr/local/lib/node_modules/npm/lib/config/core.js:81:7
        at Array.forEach (<anonymous>)
        at /usr/local/lib/node_modules/npm/lib/config/core.js:80:13
        at f (/usr/local/lib/node_modules/npm/node_modules/once/once.js:25:25)
        at afterExtras (/usr/local/lib/node_modules/npm/lib/config/core.js:178:20)
        at Conf.<anonymous> (/usr/local/lib/node_modules/npm/lib/config/core.js:236:22)
        at /usr/local/lib/node_modules/npm/node_modules/uid-number/uid-number.js:39:14
        at ChildProcess.exithandler (child_process.js:282:5)
        at emitTwo (events.js:126:13)
        at ChildProcess.emit (events.js:214:7)
        at maybeClose (internal/child_process.js:925:16)
        at Socket.stream.socket.on (internal/child_process.js:346:11)
    /usr/local/lib/node_modules/npm/lib/utils/error-handler.js:205
      if (npm.config.get('json')) {
                     ^
    
    TypeError: Cannot read property 'get' of undefined
        at process.errorHandler (/usr/local/lib/node_modules/npm/lib/utils/error-handler.js:205:18)
        at emitOne (events.js:116:13)
        at process.emit (events.js:211:7)
        at process._fatalException (bootstrap_node.js:378:26)
    
    The same behavior is not reproducible in the same instances but with another docker container from node 
    
    If you want to continue to use alpine you can set this variable before running npm
    
    export npm_config_user=65534
    
    which is the default uid for user nobody
    

    So the bug is that its returning the username rather than uid of the nobody user as the user id when running on m5ds using alpine (which uses libmusl), which causes the code to error as it expects a uid not a username, our workaround bypasses this logic (in most cases) to hardcode the uid.

    Kind Regards, Nathan Burrell

  4. Levent Ogut

    I am having the same issue on Google Cloud Shell FYI

    Step 29/57 : RUN npm install pm2@latest -g
     ---> Running in 45e366feb2f0
    Error: could not get uid/gid
    [ 'nobody', 0 ]
        at /usr/local/lib/node_modules/npm/node_modules/uid-number/uid-number.js:37:16
        at ChildProcess.exithandler (child_process.js:295:5)
        at ChildProcess.emit (events.js:182:13)
        at maybeClose (internal/child_process.js:962:16)
        at Process.ChildProcess._handle.onexit (internal/child_process.js:249:5)
    TypeError: Cannot read property 'get' of undefined
        at errorHandler (/usr/local/lib/node_modules/npm/lib/utils/error-handler.js:205:18)
        at /usr/local/lib/node_modules/npm/bin/npm-cli.js:76:20
        at cb (/usr/local/lib/node_modules/npm/lib/npm.js:228:22)
        at /usr/local/lib/node_modules/npm/lib/npm.js:266:24
        at /usr/local/lib/node_modules/npm/lib/config/core.js:83:7
        at Array.forEach (<anonymous>)
        at /usr/local/lib/node_modules/npm/lib/config/core.js:82:13
        at f (/usr/local/lib/node_modules/npm/node_modules/once/once.js:25:25)
        at afterExtras (/usr/local/lib/node_modules/npm/lib/config/core.js:173:20)
        at Conf.<anonymous> (/usr/local/lib/node_modules/npm/lib/config/core.js:231:22)
    /usr/local/lib/node_modules/npm/lib/utils/error-handler.js:205
      if (npm.config.get('json')) {
                     ^
    TypeError: Cannot read property 'get' of undefined
        at process.errorHandler (/usr/local/lib/node_modules/npm/lib/utils/error-handler.js:205:18)
        at process.emit (events.js:182:13)
        at process._fatalException (internal/bootstrap/node.js:472:27)
    The command '/bin/sh -c npm install pm2@latest -g' returned a non-zero code: 7
    Makefile:14: recipe for targe
    
  5. Vladimir Kazakov

    I'm using the node:8-jessie image and faced with the same issue.

    warning "webpack > ajv-keywords@1.5.1" has unmet peer dependency "ajv@>=4.10.0".
    warning " > karma-jasmine@0.3.8" has unmet peer dependency "jasmine-core@*".
    warning " > pug-loader@2.3.0" has unmet peer dependency "pug@>=2.0.0-beta3 <3".
    error An unexpected error occurred: "EACCES: permission denied, mkdir '/workdir/node_modules/abbrev'".
    info If you think this is a bug, please open a bug report with the information provided in "/workdir/yarn-error.log".
    info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
    
  6. Joaquin Cuenca Abela

    Same problem as Vladimir, we were on Alpine, switched to jessie and it still fails after clearing the caches.

    I actually tried the node:11 image, not Alpine based, and it's still failing. We run this image with docker-compose, the pipeline image (configured in image: in bitbucket-pipeline.yml) is Alpine. See: https://bitbucket.org/graphicresources/tutpad_web/addon/pipelines/home#!/results/3336/steps/%7Bf42a95fc-cec7-4903-99f7-50ef2b0a7f21%7D

    I also tried using Ubuntu as the bitbucket-pipeline.yml image, running node:11 with docker-compose, and it still fails with the same error, see:

    https://bitbucket.org/graphicresources/tutpad_web/addon/pipelines/home#!/results/3340/steps/%7Bc5682f5c-625f-46b7-ad65-f188e609ba30%7D

    (I set the image with the sha2 hash to prevent the cache from using a previous version.)

    Is there another bug unrelated to this one with the same symptoms?

    Thanks!

  7. JoshuaE

    I'm getting absolutely no joy from attempting any of the suggestions. Can somebody please reach out and give us a clue on how to rectify this issue? My error is exactly the same as what Vladimir (above) is seeing. I've tried node:10-stretch as well... I've tried unsetting the NPM_CONFIG_USER as per another thread.

    I'm really quite stuck with this - I can confirm the bower modules (yes, I know, but it's a legacy app) are being installed without issue; but yarn/npm are failing with the error outlined by Vladimir.

    @Philip Hodder

  8. Log in to comment