Virtual-environments: Npm i -g without sudo

Created on 22 Mar 2020  路  7Comments  路  Source: actions/virtual-environments

Why is sudo needed to run npm i on MacOS and Ubuntu? If I run it without sudo, i get the eaccess permission denied error.

If this would work without sudo, I could do matrix workflows over all 3 platforms, but as Windows doesn't know sudo, I can't do that...

Packages Ubuntu macOS question

Most helpful comment

@hrueger Try running actions/setup-node before installing anything globally with npm. I've run into this problem and doing this seems to fix the permissions, even though node and npm are already pre-installed on the runners.

- uses: actions/setup-node@v1
  with:
    node-version: '12.x'
- name: Install
  run: npm install -g nativescript

All 7 comments

Hello, @hrueger
Could you please provide steps to reproduce the issue?

For example, I don't use sudo:

on: push
jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [macos-latest, ubuntu-latest]
    steps:
     - name: npm i
       run: |
         git clone https://github.com/cnpm/npminstall
         cd npminstall
         npm i

Sure, I did some more tests and found out that it only happens on Ubuntu (MacOS is fine now, I don't know why) and only when a package is installed globally. The project where I ran npm i originally had a dependency which had a posinstallscript which tried to install another package globally.

You can see my test action here: https://github.com/hrueger/npm-i-sudo-tests/runs/528174020. I only try to install nativescript globally.

My workflow file looks as follows:

name: "Test"

on: [push]

jobs:
  osxUbuntuNoSudo:
    strategy:
      matrix:
        os: [ubuntu-latest, macOS-latest]
      fail-fast: false
    name: No sudo on ${{matrix.os}} 
    runs-on: ${{matrix.os}}
    steps:
    - uses: actions/checkout@v1
    - name: Install
      run: npm install -g nativescript
  osxUbuntuWithSudo:
    strategy:
      matrix:
        os: [ubuntu-latest, macOS-latest]
      fail-fast: false
    name: Sudo on ${{matrix.os}} 
    runs-on: ${{matrix.os}}
    steps:
    - uses: actions/checkout@v1
    - name: Install
      run: sudo npm install -g nativescript

The Ubuntu job without sudo is failing.

@hrueger , The /usr/local/lib/node_modules folder has owner root. A normal user can't write to system folder. In your case, running the installation command with sudo gives you the permissions of the superuser, and allows you to modify files that your normal user doesn't have permission to modify the directory /usr/local/lib/node_modules/. The root user does, and so the installation is successful.

Workaround:

  1. Use NPM_CONFIG_PREFIX - https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally
export NPM_CONFIG_PREFIX=~/.npm-global
npm install -g nativescript

ENV:

- name: NPM
      env:
        NPM_CONFIG_PREFIX: "~/.npm-global"
      run: |
        npm install -g nativescript
  1. Use sudo
    sudo npm install -g nativescript

  2. Change owner
    sudo chown -R $USER /usr/local/lib/node_modules

@al-cheb Thanks for the quick response! That makes sense.

Is there any chance that that folder will be changed to a folder which is writable for non-root users by default in the future? Or does that have (security) drawbacks?

@hrueger, You should follow the recommendation - "In general, all packages should be installed locally(local packages are installed in the directory where you run npm install , and they are put in the node_modules folder under this directory)." (https://nodejs.dev/npm-global-or-local-packages). Updating a global package would make all your projects use the new release, and as you can imagine this might cause nightmares in terms of maintenance, as some packages might break compatibility with further dependencies, and so on.

WebPack: Note that this is not a recommended practice. Installing globally locks you down to a specific version of webpack and could fail in projects that use a different version.(https://webpack.js.org/guides/installation/#global-installation)

It's very serious security drawbacks for production system when non-root user can write to system folders. I think it's possible to change default behavior in future,

@hrueger Try running actions/setup-node before installing anything globally with npm. I've run into this problem and doing this seems to fix the permissions, even though node and npm are already pre-installed on the runners.

- uses: actions/setup-node@v1
  with:
    node-version: '12.x'
- name: Install
  run: npm install -g nativescript

@hrueger, by default actions/setup-node@v1 task is using /opt/hostedtoolcache as an installation path where all users can able to write.
npm config get prefix : /opt/hostedtoolcache/node/

Free free to open the thread if you have any concerns.

Was this page helpful?
0 / 5 - 0 ratings