nvm icon indicating copy to clipboard operation
nvm copied to clipboard

Unable to use `nvm`, `node` and `npm` with sudo

Open AbrahamNuno opened this issue 3 years ago • 15 comments

Operating system and version:

Ubuntu 20.04.3 LTS

nvm debug output:

❯ nvm debug
nvm --version: v0.39.1
$SHELL: /usr/bin/zsh
$SHLVL: 1
whoami: 'lnuno'
${HOME}: /home/lnuno
${NVM_DIR}: '${HOME}/.nvm'
${PATH}: ${NVM_DIR}/versions/node/v14.18.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:${HOME}/OM/projects/mms/gwctl
$PREFIX: ''
${NPM_CONFIG_PREFIX}: ''
$NVM_NODEJS_ORG_MIRROR: ''
$NVM_IOJS_ORG_MIRROR: ''
shell version: 'zsh 5.8 (x86_64-ubuntu-linux-gnu)'
uname -a: 'Linux 5.11.0-46-generic #51~20.04.1-Ubuntu SMP Fri Jan 7 06:51:40 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux'
checksum binary: 'sha256sum'
OS version: Ubuntu 20.04.3 LTS  
curl: /usr/bin/curl, curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
wget: /usr/bin/wget, GNU Wget 1.20.3 built on linux-gnu.
git: /usr/bin/git, git version 2.25.1
ls: cannot access 'grep:': No such file or directory
grep: grep: aliased to grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn,.idea,.tox} (grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn,.idea,.tox}), grep (GNU grep) 3.4
awk: /usr/bin/awk, awk: not an option: --version
sed: /usr/bin/sed, sed (GNU sed) 4.7
cut: /usr/bin/cut, cut (GNU coreutils) 8.30
basename: /usr/bin/basename, basename (GNU coreutils) 8.30
rm: /usr/bin/rm, rm (GNU coreutils) 8.30
mkdir: /usr/bin/mkdir, mkdir (GNU coreutils) 8.30
xargs: /usr/bin/xargs, xargs (GNU findutils) 4.7.0
nvm current: v14.18.3
which node: ${NVM_DIR}/versions/node/v14.18.3/bin/node
which iojs: iojs not found
which npm: ${NVM_DIR}/versions/node/v14.18.3/bin/npm
npm config get prefix: ${NVM_DIR}/versions/node/v14.18.3
npm root -g: ${NVM_DIR}/versions/node/v14.18.3/lib/node_modules

nvm ls output:

❯ nvm ls
       v12.22.9
->     v14.18.3
       v16.13.2
default -> lts/fermium (-> v14.18.3)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.13.2) (default)
stable -> 16.13 (-> v16.13.2) (default)
lts/* -> lts/gallium (-> v16.13.2)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.9
lts/fermium -> v14.18.3
lts/gallium -> v16.13.2

How did you install nvm?

Followed the instructions in the section Installing and Updating of the README.md. I also followed the steps in Deeper Shell Integration in order to call nvm use automatically in a directory with a .nvmrc file, so I updated my $HOME/.zshrc.

What steps did you perform?

Everything works fine, I can install different versions of NodeJs/NPM and switch them as per my needs with no issues.

What happened?

The problem came when I tried to install globally a package with sudo. The output of the command sudo npm i -g <package-name> was:

sudo: npm: command not found

Then I tried something simple with node and nvm like checking the versions and the result was the same:

❯ nvm --version
0.39.1

❯ sudo nvm --version
sudo: nvm: command not found

❯ node -v 
v14.18.3

❯ sudo node -v
sudo: node: command not found

❯ npm -v      
6.14.15

❯ sudo npm -v
sudo: npm: command not found

What did you expect to happen?

I expect all those commands work with sudo as well, just like when NodeJS/NPM are installed in my system without NVM.

Is there anything in any of your profile files that modifies the PATH?

I just add an specific directory to the PATH, so I have the next line in my $HOME/.zshrc file:

export PATH=$PATH:~/projects/mms

AbrahamNuno avatar Jan 12 '22 16:01 AbrahamNuno

You’re not supposed to use them with sudo. nvm is per-user, and you run every command as yourself.

ljharb avatar Jan 12 '22 16:01 ljharb

Additionally, almost nothing should be globally installed anyways, and having to use sudo for it is a bad thing.

ljharb avatar Jan 12 '22 16:01 ljharb

Hi @ljharb, I agree, I normally install all my packages locally in the project's directory, except for 2 or 3 packages that are not part of the project but I like to use them no matter the project, such as rifraf and npm-check-updates.

In fact, I was trying to update npm-check-updates to the latest version when I came across with this issue.

I also agree to nvm is installed per-user and I should run it as myself, but still I think node and npm should be able to run with sudo, just like an standard installation with no nvm.

AbrahamNuno avatar Jan 12 '22 16:01 AbrahamNuno

They should not and can not, due to the nature of linux and that nvm is not installed under the root user.

Using sudo with npm install -g is not a feature, it is a burden - one nvm liberates you from.

ljharb avatar Jan 12 '22 16:01 ljharb

Using sudo with npm install -g is not a feature, it is a burden - one nvm liberates you from.

Ok. I think this should be documented better in the installation page / README.md

I've seen some confusion why nvm alias default system doesn't work - sounds like, unless you have a legacy install, it can never work; we've been freed. This is important if installing an application that does require 'sudo' to work, and leads to confusing about misusing the nvm alias default system command.

I was hoping sudo nvm alias default system would setup the system default, as have others on stack overflow.

Can we guide people to the correct use?

jgwinner avatar Aug 08 '22 23:08 jgwinner

@jgwinner happy to review PRs to improve the documentation!

One important point is that nvm is per-shell, per-user - so it simply doesn't ever work with sudo.

ljharb avatar Aug 09 '22 00:08 ljharb

@ljharb I am trying to install Ghost CMS, the instructions say to run sudo npm install ghost-cli@latest -g except Ghost needs a newer version of Node than came with Ubuntu.

Are you saying that I don't install NVM for root to updated the version of node that my root user has access to?

adampatterson avatar Jan 02 '23 02:01 adampatterson

@adampatterson i'm saying that you should ignore the sudo part of those instructions when using nvm, because nvm-managed nodes don't require root permissions to install global packages.

ljharb avatar Jan 02 '23 04:01 ljharb

I am trying to run command as a user but from root user and running sudo -u myuser nvm ls results in sudo: nvm: command not found. Actual myuser result for nvm ls is default -> 14 (-> v14.21.2). Any suggestion how to resolve this? Tried adding symlink ln -s /home/myuser/.nvm/versions/node/v14.21.2/bin/node /sbin/node but then the error is Sorry, user "root" is not allowed to execute '/usr/sbin/node' as myuser. In areal pickle because the command is run on CodeDeploy as root.

slejnej avatar Feb 01 '23 17:02 slejnej

@slejnej the resolution is "don't use sudo", or, "install nvm as root also". Each user needs its own nvm install.

ljharb avatar Feb 01 '23 17:02 ljharb

@ljharb root user has installed same version as user. And nvm, node, npm are all symlinked to all bin folders so that sudo (sbin), root and any other non admin user could run it, but no luck. We do want to execute it as myuser but because CodeDeploy is run as root there the command we want to run is as non root user sudo -u myuser npm install is not found.

slejnej avatar Feb 02 '23 08:02 slejnej

nvm does not support symlinks like that.

ljharb avatar Feb 02 '23 16:02 ljharb

@slejnej I had the same problem with an app (ERPNext). It expects certain node versions, but despite running as a specific user, occasionally has to issue commands via sudo.

Our solution was to forget NVM, and just purpose build a box with all consistent versions of both Python and Node, thus eliminating the need for NVM. We had to match O/S version to make sure we got the right Python version.

Without commenting on the appropriateness, NVM and root will never play together because of the overall philosophy of NVM, so I wouldn't fight it if you can avoid it. Sounds like you have the same situation. The good news is containers and VM's are easy to spin up to purpose build a consistent architecture.

NVM is really great for development, but you wouldn't go into production or test with a dev build.

That worked for us.

jgwinner avatar Feb 02 '23 17:02 jgwinner

@jgwinner what I've ended up doing is re-ordering the CodeDeploy hooks, so that npm, composer and testing is run in later (not dedicated) step so moving things from AfterInstall to later ApplicationStart stage and run all as a user only on that hook but still had to symlink npm and node to /usr/bin/node & npm. Thanks

slejnej avatar Feb 02 '23 17:02 slejnej

YW. Was really just giving you our approach, and for others running into the issue; doesn't mean it's best for you!

Sounds good.

jgwinner avatar Feb 02 '23 17:02 jgwinner