Enable npm install -g for all users - node.js

I am trying to install node in a way that make all users able to install npm packages globally without sudo access rights.
Usually, you can find on the internet people saying that you should do:
npm config set prefix $HOME/.npm-packages
However $HOME is good only for a single user.
So I went with this code:
# Install node
sudo apt install -y curl
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt install -y nodejs
# Set node global packages folder as /usr/local/lib/node_modules
NPM_PACKAGES="/usr/local/lib/node_modules"
sudo mkdir -p $NPM_PACKAGES
sudo chmod 777 $NPM_PACKAGES
npm config set prefix $NPM_PACKAGES
# Update the path and manpath to read from npm packages
echo "export PATH="\""\$PATH:$NPM_PACKAGES/bin"\""
export MANPATH="\""\${MANPATH-\$(manpath)}:$NPM_PACKAGES/share/man"\" | sudo tee '/etc/profile.d/node-path.sh'
source /etc/profile.d/node-path.sh
When I try to install pm2 with npm with another user, I get:
npm ERR! code EACCES
npm ERR! syscall symlink
npm ERR! path ../lib/node_modules/pm2/bin/pm2
npm ERR! dest /usr/bin/pm2
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, symlink '../lib/node_modules/pm2/bin/pm2' -> '/usr/bin/pm2'
Apparently, I should execute npm config set prefix $NPM_PACKAGES for every user.
So I have 4 questions:
Is this approach correct for what I am trying to achieve?
Is /usr/local/lib/node_modules a good choice for the npm packages, or is there a better place?
Is there a way to npm config set prefix once and for all users?
If not, should I add that to the /etc/profile.d/node-path.sh file?

Ok. After all the materials I could find on the web and the expermients I could make, I reached the following conclusion. If I'm mistaken, please feel free to correct me.
This is indeed the correct way to enable npm install -g for all users and share the installed libraries
/usr/local/lib/node_modules is the target I found most of the time in related topics, even if it was not really about the exact same thing.
I couldn't find anything about setting npm config set prefix for all users. There is indeed a npm config --global command, but it didn't seem to work for this case. But maybe I missed something.
I ended up adding this line to the /etc/profile.d/node-path.sh and it works. If someone think that it is not the correct way to do so, please comment.
In the end, this is the way I create my node-path.sh:
# Update the path and manpath to read from npm packages
echo "export PATH="\""\$PATH:$NPM_PACKAGES/bin"\""
export MANPATH="\""\${MANPATH-\$(manpath)}:$NPM_PACKAGES/share/man"\""
npm config set prefix $NPM_PACKAGES" | sudo tee '/etc/profile.d/node-path.sh'
In conclusion, the correct way to enable ̀npm install -g` for all users seems to be:
# Install node
sudo apt install -y curl
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt install -y nodejs
# Set node global packages folder as /usr/local/lib/node_modules
NPM_PACKAGES="/usr/local/lib/node_modules"
sudo mkdir -p $NPM_PACKAGES
sudo chmod 777 $NPM_PACKAGES
# Update the path and manpath to read from npm packages
echo "export PATH="\""\$PATH:$NPM_PACKAGES/bin"\""
export MANPATH="\""\${MANPATH-\$(manpath)}:$NPM_PACKAGES/share/man"\""
npm config set prefix $NPM_PACKAGES" | sudo tee '/etc/profile.d/node-path.sh'
source /etc/profile.d/node-path.sh

Related

Fix for npm global install on Ubuntu

I have a nodejs package that requires a global install. This one fails in a way that leads me to believe there might be a configuration problem in the the Ubuntu package npm. This happens every-time I setup an Ubuntu 14.04 machine.
sudo apt-get install npm
npm install -g lineman
The npm -g command will throw some access error naming the local lib and bin directories. Unlike some global installs, it is not an option to cheat and run the second command under sudo. So, the only fix I have found that will work is something like this:
sudo chgrp -R $(whoami) /usr/local/bin /usr/local/lib
sudo chmod -R g+rwx /usr/local/bin /usr/local/lib
The fix is fine for me, I'm the only user. But is this really the best way to do it? I don't want to document my fix for anyone else that might use it in an environment where this will not work or cause trouble.
Also, should I file a bug report with someone who packages npm for Ubuntu?
Instead of npm install -g lineman, you should run sudo npm install -g lineman. npm requires permission as well.
Also check this stackoverlfow link.

npm upgrade with homebrew

When node (v.0.10.33) is installed with homebrew (v. 0.9.5), at one point it says:
==> Caveats
If you update npm itself do NOT use the npm upgrade command
Instead execute:
npm install -g npm#latest
So, what exactly is npm upgrade and what is the difference with npm install -g npm#latest?
-- edit 2015
the problem doesn't exist anymore with the current version of node. (but I never had an answer to what npm upgrade is?)
Use npm install to install a package and npm update to update a package.
That Homebrew npm caveat was removed after the issue with npm update -g was fixed.
npm comes bundled with node, both part of Node.js install --- no need to install separately
Below are the steps to install Node.js from source (OSX/linux)
Issue cmds as yourself NOT root (sudo)
to start fresh remove prior node and npm installs as well as these :
sudo mv ~/.npmrc ~/.npmrc_ignore
sudo mv ~/.npm ~/.npm_ignore
sudo mv ~/tmp ~/tmp_ignore
sudo mv ~/.npm-init.js ~/.npm-init.js_ignore
download source from : http://nodejs.org/download/
cd freshly-downloaded-dir
define environment variable NODE_PATH as the dir for subsequent module installs
export NODE_PARENT=${HOME}/nodejs-v0.10.33
export PATH=${NODE_PARENT}/bin:${PATH}
export NODE_PATH=${NODE_PARENT}/lib/node_modules
./configure --prefix=${NODE_PARENT}
make
make install # IMPORTANT this is NOT using sudo
# not wanted since installing into $USER owned $NODE_PARENT
which puts it into dir defined by above --prefix
when you use syntax : npm install -g some_cool_module
the -g for global installs it into dir $NODE_PATH and not your $PWD
Now put above three export xxx=yyy
commands into your ~/.bashrc or some such to persist these environment variable changes

How do I know whether I have Node.js and npm successfully installed on Ubuntu 14.04?

I installed Node.js with these instructions and it seemed successful:
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
Then I installed npm with these instructions:
sudo curl https://www.npmjs.org/install.sh | sh
The nodejs installation seemed to work without errors but the npm command gave me a lot of errors. But it seems like they are installed because when I test what version I have they both come up:
nodejs -v
v0.10.30
npm -v
1.4.21
So If this doesn't tell me that I have both programs successfully installed, which I assume I do not, how do I know?
I think your tests tell that both or properly installed.
But you can try just type node in terminal & it should open a node shell, where you can check by running basic commands.
Current distributions of node.js (including the one you downloaded) already include npm. So maybe installing npm manually is one source of your errors. Beware that usually you run "npm install" with the permissions of a regular user. There are only some npm-based utilities that are to be installed with root permissions and the '-g' (global) command line switch.
On linux if you wish to install node.js and npm as yourself NOT root :
to start fresh remove prior node.js and npm installs as well as these :
~/.npmrc
~/.npm
~/tmp
~/.npm-init.js
create your ~/bin/ directory if not already created :
mkdir ${HOME}/bin
download source from : http://nodejs.org/download/
cd node-v0.10.30/
./configure --prefix=${HOME}/bin/nodejs
make -j8
make install
which puts it into dir defined by above --prefix
export PATH=${HOME}/bin/nodejs/bin:$PATH
define NODE_PATH so node can find dir for modules otherwise
npm install xxx will put newly installed module into dir in curr dir :
export NODE_PATH=${HOME}/bin/nodejs/lib/node_modules
do above AND use syntax :
npm install xxxxx -g
always use the -g for global which puts package xxxxx into $NODE_PATH
NOTE - nodejs install gives you npm as well :
ls -la ${HOME}/bin/nodejs/bin

NPM cannot install dependencies - Attempt to unlock something which hasn't been locked

I've been trying to run an npm install on my package.json file, but I'm having a lot of trouble. It keeps saying "Error: Attempt to unlock XXX, which hasn't been locked" on all my dependences. Here's one of them:
Error: Attempt to unlock tbd#~0.6.4, which hasn't been locked
at unlock (/usr/local/lib/node_modules/npm/lib/cache.js:1304:11)
at cb (/usr/local/lib/node_modules/npm/lib/cache.js:646:5)
at /usr/local/lib/node_modules/npm/lib/cache.js:655:20
at /usr/local/lib/node_modules/npm/lib/cache.js:1290:7
at /usr/local/lib/node_modules/npm/node_modules/lockfile/lockfile.js:167:38
at OpenReq.Req.done (/usr/local/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:144:5)
at OpenReq.done (/usr/local/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:64:22)
at Object.oncomplete (fs.js:107:15)
If I try to run it as sudo, it seems to get further and start installing some packages, but some new errors popup instead:
> chokidar#0.8.1 postinstall /Users/tkirchner/Documents/Projects/mm-datatable/node_modules/karma/node_modules/chokidar
> node setup-deps.js
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
node.js:811
var cwd = process.cwd();
^
Error: EACCES, permission denied
at Function.startup.resolveArgv0 (node.js:811:23)
at startup (node.js:58:13)
at node.js:902:3
npm ERR! error rolling back Error: ENOTEMPTY, rmdir '/Users/tkirchner/Documents/Projects/mm-datatable/node_modules/karma/node_modules/q'
npm ERR! error rolling back karma#0.10.9 { [Error: ENOTEMPTY, rmdir '/Users/tkirchner/Documents/Projects/mm-datatable/node_modules/karma/node_modules/q']
npm ERR! error rolling back errno: 53,
npm ERR! error rolling back code: 'ENOTEMPTY',
npm ERR! error rolling back path: '/Users/tkirchner/Documents/Projects/mm-datatable/node_modules/karma/node_modules/q' }
npm ERR! Error: ENOENT, chown '/Users/tkirchner/Documents/Projects/mm-datatable/node_modules/karma/node_modules/socket.io/lib/socket.io.js'
I recently updated my node and npm installations. So maybe that has something to do with it. Also, most of my development has been at the office and today I'm working over VPN, so maybe that has something to do with it too.
Any ideas?
As per photusenigma at: https://github.com/npm/npm/issues/4815
Run these commands in a terminal window (note - DON'T replace the $USER part...thats a linux command to get your user!):
sudo chown -R $USER ~/.npm
sudo chown -R $USER /usr/local/lib/node_modules
...and...if you're on a mac (like I am), and still see errors after running these commands, then run this last one and you should be good. (Recommend you try testing before you do this one. I don't like changing the permissions on the ENTIRE /usr/local directory unless it really seems necessary!)
sudo chown -R $USER /usr/local
I worked with a co-worker this afternoon and figured out what the problem was. My ".npm" folder in my home directory was owned by the root user instead of myself. I'm not sure what happened to cause that. Maybe I installed node or npm as the root admin at one point. In any case I just ran sudo chown -R [username] .npm and I was finally able to run npm install commands from my projects again!
In my case the issue was invoking npm with a user that does not have a HOME directory, so for example the following command would fail:
sudo -u someUser npm install
The solution is to provide a HOME directory, where someUser has write access:
sudo -u someUser HOME=/some/directory npm install
Had the same issue and fixed it by changing the persmissions as per the accepted answer:
sudo chown -R $USER ~/.npm
However, the second command should be avoided as it downgrades the permissions of a system resource (sudo chown -R $USER /usr/local/lib/node_modules). Not a good idea.
For the record: "usr" in /usr/local stands for Unix System Resources.
None of this worked for me. I had to run literally as root by doing the following:
sudo su -
sudo npm install forever -g
Then the package installed on Linux Ubuntu 14.04.
The following command should fix permission issues:
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
You can read about another officially recommended solutions here:
https://docs.npmjs.com/getting-started/fixing-npm-permissions
My solution:
sudo chown -R $USER /usr/local/lib/node_modules/NAMEOFMODULE
in my case was :
sudo chown -R $USER /usr/local/lib/node_modules/appium/
But I was getting the same problem, finally after
npm cache clean
it worked !
I had the same problem and tried to fix the permission/ownership of npm related files and directories for hours but had no luck with that.
Suddenly I found that I had ~/.npmrc file with cache entry pointing to a non-existing directory. Removed that cache property to use the default cache location and now it's solved.
Disclaimer
I am a Windows user. However, my team and I have come across a number of issues regarding npm installaion errors.
Problems
The following is a list of lessons learned and a possible radical solution that has always rescued us:
node_modules, the npm local installation directory becomes protected from modification by a shortcoming of the OS such as the inability to process paths longer than 255 characters.
If the folder is erased by means of a command line tool it may still appear as if the folder exists in the explorer that when trying to access it gives a number of permission errors.
Depending on your antivirus and/or local policy manager you may be able to create the node_modules folder and later relegated access or permissions to it resulting in a number of installation errors.
Enable npm logs to gain further insight into possible problems with:
npm install --loglevel verbose
Radical
Install rimraf globally
npm install rimraf -g
Run rimraf on node_modules:
rimraf yourDir/node_modules
Then try running:
npm install
Warning!
Or lack there of. Be extremely careful about what follows the command rimraf. There are no warnings, no prompts, there is nothing. It simply erases the directory from the phase of the earth clean, as if it was never there. Try it at your own risk.
for me, it was my proxy... and make sure to delete package-lock.json.
this worked for me on my mac / unix based system:
npm config rm proxy
npm config rm https-proxy
npm config delete proxy
npm config delete https-proxy
npm config --global rm proxy
npm config --global rm https-proxy
npm config set registry "http://registry.npmjs.org"
npm config set strict-ssl false
npm install
run: scutil --proxy
you should get dictionary list...
then get these values from that list:
HTTPProxy : 127.0.0.1 HTTPPort : 8118
then include them in this command:
npm config set proxy http://127.0.0.1:8119
then include this:
npm config set https-proxy https://123.0.0.1:8118
reference: https://www.sneppets.com/angular/how-to-make-npm-install-command-to-work-behind-proxy/

NPM modules won't install globally without sudo

I have just reinstalled Ubuntu 12.04 LTS, and before anything else i did these steps:
Installed Node via package manager with the following script
sudo apt-get update
sudo apt-get install python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
Tried to install yeoman, express, n, yeoman's generators globally and all of them returned the same error
npm ERR! Error: EACCES, symlink '../lib/node_modules/n/bin/n'
npm ERR! { [Error: EACCES, symlink '../lib/node_modules/n/bin/n'] errno: 3, code: 'EACCES', path: '../lib/node_modules/n/bin/n' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! System Linux 3.8.0-29-generic
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install" "-g" "-d" "n"
npm ERR! cwd /home/heberlz
npm ERR! node -v v0.10.20
npm ERR! npm -v 1.3.11
npm ERR! path ../lib/node_modules/n/bin/n
npm ERR! code EACCES
npm ERR! errno 3
npm ERR! stack Error: EACCES, symlink '../lib/node_modules/n/bin/n'
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/heberlz/npm-debug.log
npm ERR! not ok code 0
Reclaimed ownership of the following folders recursively ~/.npm, /usr/lib/node, /usr/lib/node_modules, and of the following symlinks /usr/bin/node, /usr/bin/nodejs with absolutely no success
I need to install yeoman and its generators without sudo not to be in trouble later on :(
Ubuntu 12.04 and using Chris Lea's PPA for install the following works for me:
npm config set prefix '~/.npm-packages'
and adding $HOME/.npm-packages/bin to $PATH
Append to .bashrc
export PATH="$PATH:$HOME/.npm-packages/bin"
For more see this answer from #passy
If you already have $HOME/bin in your path, a simpler solution is just ...
npm config set prefix ~
New node commands will now install into your $HOME/bin directory.
No need to change your path!
Since this discussion is really about reducing the security risks of running sudo, you should also be aware that any node app could potentially be installing an app name that does not match the registered node package name you think you're installing. So there is a security risk that an npm install will replace an existing system command or one you already have in $HOME/bin. If you're concerned, check the bin, and scripts properties in the package.json file of the app you're installing first.
In general, it's safest to:
(a) Place $HOME/bin last in your path so system commands are not superseded.
(b) don't include "." or any relative path in your $PATH so you don't accidentally run a command that happens to be in the current directory.
Reference:
package.json properties
npm install
NodeJS security vulnerabilities: nodesecurity.io.
As for October 2014:
Node.js is available from the NodeSource Debian and Ubuntu binary distributions repository.
curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get install -y nodejs
That's it.
Outdated answer:
The fastest way without using sudo is like described here by isaac
I strongly encourage you not to do package management with sudo!
Packages can run arbitrary scripts, which makes sudoing a package
manager command as safe as a chainsaw haircut. Sure, it's fast and
definitely going to cut through any obstacles, but you might actually
want that obstacle to stay there.
I recommend doing this once instead:
sudo chown -R $USER /usr/local
EDIT:
There are certain security concerns and functionality limitations regarding changing the ownership of /usr/local to the current user:
if there is another user on the machine who could use global npm packages - do not change the ownership of /usr/local
https://apple.stackexchange.com/questions/1393/are-my-permissions-for-usr-local-correct
https://askubuntu.com/questions/261326/is-it-safe-to-chown-usr-local
Having said that, if you want to install global module without using sudo, I don't see any better solution (from pragmatic point of view) than mentioned. Security vs easy of use is very broad topic, and there is no easy answer for that - it just depends on your requirements.
The issue was i installed node using sudo, to avoid errors when installing npm modules globally one MUST NEVER install node with sudo.
My solution was to reinstall node it this way:
Download latest stable node sources from nodejs.org #in my case node-v0.10.20.tar.gz
tar -zxf node-v0.10.20.tar.gz #uncompress sources
cd node-v0.10.20 #enter uncompressed folder
sudo chown -R $USER /usr/local
./configure --prefix=/usr/local && make && make install
One thing to note is that only taking ownership of the /usr/local folder wouldn't work in my case because node installation itself was made with sudo
Last step to install yeoman: #although at yeoman.io it says that doing "npm install -g yo" already installs bower and grunt, there are some submodules of grunt that fail, so i fixed that by installing it by itself
npm install -g bower
npm install -g grunt
npm install -g yo
npm install -g generator-angular
I solved this problem with environment variable and shell alias:
export NPM_PREFIX=$HOME/node
alias npmg="npm -g --prefix $NPM_PREFIX"
For me npm did not honor the "prefix" config setting in .npmrc.
Find the path to npm's directory:
npm config get prefix
For many systems, this will be /usr/local.
Change the owner of npm's directories to the name of the current user (your username!):
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
This changes the permissions of the sub-folders used by npm and some other tools (lib/node_modules, bin, and share).
Here is the link for full details
https://docs.npmjs.com/getting-started/fixing-npm-permissions
According to this similar SO post: npm throws error without sudo
Looks like you might have an ownership issue with ~/.npm directory.
As with the answer in that one, try:
sudo chown -R `whoami` ~/.npm
If you're on a developping machine, you might be better off considering using nvm.
If not, you simply want to install using your favorite package manager.
Whatever the case may be, I'd recommend checking this answer on stackoverflow
Actually, I just changed the permission of a user folder that was owned by root:
sudo chown -R $USER ~/.config/configstore
Then I could "npm install" and "bower install" without sudo!
Worked fine!
using lubuntu 14.04.3, I tried changing ownership of .npm and npm prefix, updated my path, npm installed modules to my home directory without sudo but the path was incorrect so the modules like ember were not found, linuxbew solved the problem, quick setup guide here for node/npm
This issue and other caused by the same reason can be solved installing Node in user space.
You can do it just copying and pasting in your terminal
NODEJS_ROOT=${NODEJS_ROOT:-~/nodejs}
cd /tmp
wget -N http://nodejs.org/dist/node-latest.tar.gz && tar xzf node-latest.tar.gz
NODEJS_CURRENT=$(tar tf node-latest.tar.gz|head -1)
mkdir -p $NODEJS_ROOT/$NODEJS_CURRENT
cd $NODEJS_CURRENT
./configure --prefix=$NODEJS_ROOT/$NODEJS_CURRENT && make install
cd $NODEJS_ROOT
rm current 2> /dev/null # Removes current symbolic link, if any
ln -s $NODEJS_CURRENT current
Same commands can be launched also to get Node updated to latest version.
Don't forget to edit your environment. Only once, do
echo "export NODEJS_ROOT=$NODEJS_ROOT" >> $HOME/.bash_profile
echo 'export PATH=$NODEJS_ROOT/current/bin:$PATH' >> $HOME/.bash_profile
source $HOME/.bash_profile # reload your env, so you can use node right now
Check out this article as a reabout how to Install Node.js without sudo.
For a more general solution about this topic (i.e., install software locally) see dotsoftware.
just use nvm
you will be able to dynamically switch between different node versions and it is installed locally for your user. No sudo needed. Just make sure you have fully cleaned up the old node beforehand.
https://github.com/nvm-sh/nvm
In order to install Node.js and npm locally without having to use sudo open the terminal and type:
echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc
. ~/.bashrc
mkdir ~/local
mkdir ~/node-latest-install
cd ~/node-latest-install
wget -c http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install
wget -c https://www.npmjs.org/install.sh | sh
Use NVM
I had the same "permission denied" issue. Instead of trying to fix the NodeJS installed from https://nodejs.org/en/ which installs into folders that are owned by root instead of $USER, I used NVM. node version manager.
Install it: run curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
Install a version of node: run nvm install 16
Use it:
nvm use 16
npm install -g yarn
Everything worked fine when I used Node installed by NVM.
The best solution I found was to install Node.js from the tar package on to user home directory & link the lib folder location. Here is what you need to do
This will install Nodejs under ~/.local/ instead of the default /usr/local/
Add this to your ~/.npmrc (create the file if it doesn't exist already):
root = /home/YOUR-USERNAME/.local/lib/node_modules
binroot = /home/YOUR-USERNAME/.local/bin
manroot = /home/YOUR-USERNAME/.local/share/man
Download the Nodejs source code from nodejs.org and install it under your ~/.local tree:
tar xf node......
cd node........
./configure --prefix=~/.local
make
make install
Create ~/.node_modules symlink. (This directory will be automatically searched when you load modules using require "module" in scripts. I'm not sure why Node doesn't search ~/.local/lib/node_modules by default.)
cd
ln -s .local/lib/node_modules .node_modules
Is ~/.local/bin in your path? Type
which npm
If it says ~/.local/bin/npm, you're done.
Otherwise, do this...
export PATH=$HOME/.local/bin:$PATH
...and add that line to your ~/.profile file, so it'll run every time you log in.
If you still encounter ownership or permission error while installing packages, then change ownership of ~/.local/ dir by running
chown -R user:user ~/.local/
Now you should be good to install packages via 'npm'
Note: ALL OF THE ABOVE COMMANDS ARE TO BE RUN AS USER. DO NOT USE SUDO OR ROOT LOGIN
NEVER EVER CHANGE THE PERMISSION OF FOLDERS UNDER '/USR/LIB/'. WILL LEAD TO UNSTABLE OS
I find Pawel Grzybek's explanations very convincing: They boil down to 3 simple sudo commands, never having to use sudo again for global npm installs:
sudo chown -R $(whoami) /usr/local/lib/node_modules
sudo chown -R $(whoami) /usr/local/bin
sudo chown -R $(whoami) /usr/local/share

Resources