NodeJS and npm without sudo on CentOS - linux

On my box I have the Node and NPM binaries installed under /opt/node/bin. And the path is added properly.
node -v
and
npm -v
work fine. When I create a file and run it with node all works as expected. However, when I run:
npm init
the program fails to write package.json because it does not have write permission. I use:
sudo npm init
I get a file with owner and group of 0 0 and so any regular users cannot modify this file. I don't want to have to chown every file node/npm generates.
Is there way to get node/npm to run as a user in the same group as my other users and have write permissions to the same directories?

You could simply chown your /opt/ directory and future calls to npm init will be owned by you. Better yet, work in your /home folder and make sure npm and node are in your $PATH. This way you don't need to worry about permissions for initializing a new node module. You will, however, need to use sudo to install packages globally. This is bad practice according to the maintainer of Nodejs:
http://howtonode.org/introduction-to-npm
I would follow along with his setup there. As he mentions, its very dangerous to give root access to a package manager.

Related

Npm command not found after launch build.sh file

I installed nvm and then installed npm by nvm install npm.
Nvm and npm have been installed to my main directory ~/.nvm and ~/.npm.
And yes, npm command is correct in every directory in the server on the ssh connection in console.
I added also build.sh file where I wrote npm run prod command and added this in post-receive git hook.
BUT! When I send new commits to this server, I see in console note like "npm command not found".
WHY????
After all, on the server everything is okay!
I tried also move ~/.npm to /usr/local/bin/ but it wasn't help. Probably because .npm it is a folder. I don't know...
I solved problem by deleting .nvm and .npm folders and installing npm through sudo apt-get. I guess it automatically have added needs files in needs directories to make npm command globally available.
In spite of I solved the problem by another way, I want to know what I was doing incorrectly in the first approach, cause maybe in the future I need nvm. Can someone experienced in linux explain me what the problem was?
Make sure the absolute path where npm command was installed is listen within your PATH variable, then make sure you export this variable so your build.sh script can see the new value and search for npm binary.
echo $PATH
export PATH="/path/to/my/installation/:$PATH"
echo $PATH
./build.sh

NPM/Cordova permissions Error: EACCES: permission denied, scandir

When I run cordova plugin add cordova-plugin-geolocation I receive the following error. I have tried enable 777 on this folder, setting myself as the owner etc. In these circumstances I'm not allowed to use sudo, but am confident if I could that would solve the problem.
Failed to install 'cordova-plugin-geolocation': Error: EACCES: permission denied, scandir '/Users/username/documents/core/myapp/app/platforms/ios/build/device/libCordova.a'
at Error (native)
at Object.fs.readdirSync (fs.js:952:18)
at GlobSync._readdir (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:275:41)
at GlobSync._readdirInGlobStar (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:254:20)
at GlobSync._readdir (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:263:17)
at GlobSync._processReaddir (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:135:22)
at GlobSync._process (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:130:10)
at GlobSync._processGlobStar (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:360:10)
at GlobSync._process (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:128:10)
at GlobSync._processGlobStar (/Users/username/documents/core/myapp/app/platforms/ios/cordova/node_modules/glob/sync.js:363:10)
Error: EACCES: permission denied, scandir '/Users/username/documents/core/myapp/app/platforms/ios/build/device/libCordova.a'
NPM issue's
You can fix this problem using one of three options:
1).Change the permission to npm's default directory.
2).Change npm's default directory to another directory.
3).Install node with a package manager that takes care of this for you.
You should back-up your computer before moving forward.
Option 1: Change the permission to npm's default directory
1).Find the path to npm's directory:
npm config get prefix
For many systems, this will be /usr/local.
WARNING: If the displayed path is just /usr, switch to Option 2 or you will mess up your permissions.
2).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).
Option 2: Change npm's default directory to another directory
There are times when you do not want to change ownership of the default directory that npm uses (i.e. /usr) as this could cause some problems, for example if you are sharing the system with other users.
Instead, you can configure npm to use a different directory altogether. In our case, this will be a hidden directory in our home folder.
1).Make a directory for global installations:
mkdir ~/.npm-global
2).Configure npm to use the new directory path:
npm config set prefix '~/.npm-global'
3).Open or create a ~/.profile file and add this line:
export PATH=~/.npm-global/bin:$PATH
4).Back on the command line, update your system variables:
source ~/.profile
Test: Download a package globally without using sudo.
npm install -g jshint
nstead of steps 2-4 you can also use the corresponding ENV variable (e.g. if you don't want to modify ~/.profile):
NPM_CONFIG_PREFIX=~/.npm-global
Option 3: Use a package manager that takes care of this for you.
If you're doing a fresh install of node on Mac OS you can avoid this problem altogether by using the Homebrew package manager. Homebrew sets things up out of the box with the correct permission.
brew install node
For Mac users, if you are looking for a quick answer, you can edit the permissions of the .npm folder located at /Users/$(whoami)/.npm.
Go to .npm parent folder (to prevent running the 2nd command in the wrong place).
$ cd /Users/$(whoami)
Run chmod to change the permissions of the .npm folder.
$ sudo chmod -R 777 .npm/*
That's how I solved on my case.
In case anyone else arrives with a Mac cordova environment that has sudo'd itself beyond repair, this was my only solution (after a lot of pain):
backup everything
remove all cordova platforms (WARNING: this will wreck anything custom you've done within a platform, thus the backup)
uninstall cordova globally
uninstall npm; I just used the basic command from their site: sudo npm uninstall npm -g
install NVM
through that, install Node long-term-stable
install cordova (no more sudo required)
take permissions of your project directory (I did my whole user directory recursively)
add your platforms
diff back in any of your customizations
find a comfortable chair and drink scotch

Run npm as superuser, it isn't a good idea?

I'm getting errors with npm while trying to install/update packages without SU permissions on Linux.
The easy way to solve the problem is execute sudo npm install <package>, but I'm not sure if it is a good idea.
Best way is to become the owner of .npm folder, as I found into StackOverflow's questions and blog posts.
My question is: why run npm as SU it isn't a good idea?
Running npm as a super user has a risk of running some untrusted code as a super user which can potentially mess with your entire system. Running npm as an unprivileged user has a risk of running that code with less privileges and it won't be able to mess with the entire system - just with your own files (which can be equally bad, depending on how you look at it).
What I often do and recommend is to install Node in your home directory instead of globally on the system if it's your own computer. That way you don't have to run with sudo or su for npm or even for make install of Node itself.
I run a lot of versions of Node that I compile from sources sometimes with different switches and the convention that I use is to install Node in versioned directories, either globally in /opt (but then you need sudo) or locally in my home directory in ~/opt.
I do it like this:
wget https://nodejs.org/dist/v7.1.0/node-v7.1.0.tar.gz
tar xzvf node-v7.1.0.tar.gz
cd node-v7.1.0
./configure --prefix=$HOME/opt/node-v7.1.0
make && make test && make install
Then I create a symlink ~/opt/node pointing to ~/opt/node-v7.1.0 and I have:
PATH="$HOME/opt/node/bin:$PATH"
in my .profile or .bashrc.
That way I don't have to run as super user for installing Node or for running npm.
As a bonus I can quickly switch my default Node version just by changing the symlink, and at any time I can run any other version if I change the PATH or run Node with a full path like ~/opt/node-v7.0.0/bin/node.
I explained that installation process in more detail in my other answers:
node 5.5.0 already installed but node -v fetches with “v4.2.1” on OS X & homebrew?
NodeJS API with external deps in other language
I don't want to go into too much detail here since this answer is about why running npm as a superuser is not a good idea - this installation process is just one solution to not have to run npm as a superuser.
Other options of setting your npm permissions to avoid running as a superuser are described in Fixing npm permissions in npm docs (thanks to RyanZim for pointing it out in the comments).

gyp WARN EACCES user "root" does not have permission to access the dev dir

Trying to
sudo npm install protractor -g
and the same notorious error/warning again (googled to no avail):
gyp WARN EACCES user "root" does not have permission to access the dev dir "/Users/dmitrizaitsev/.node-gyp/0.12.0"
What seems to happen is that node version 0.12.0 is downloaded and rebuilt, again and again during the same installation, despite of being the current node version on my machine:
node -v
v0.12.0
Questions:
The directory "/Users/dmitrizaitsev/.node-gyp/0.12.0" is actually missing! Why such a misleading message?
Why was this directory not created neither during the node v0.12.0 nor during the previous successful rebuild with node-gyp?
(Obviously) How can I prevent this from happening?
I run Mac OSX 10.8.5 if that is of any importance.
UPDATE. There is a better way - changing npm's default global directory to user sub-directory to which you already have correct permissions, so no need to mess with system file's permissions or ownership in first place.
As recommended in
https://docs.npmjs.com/getting-started/fixing-npm-permissions:
Make a directory for global installations:
mkdir ~/.npm-global
Configure npm to use the new directory path:
npm config set prefix '~/.npm-global'
Open or create a ~/.profile (or ~/.bash_profile etc) file and add this line (at the end of the file):
export PATH=~/.npm-global/bin:$PATH
On the command line, update your system variables:
source ~/.profile
or source ~/.bash_profile
See also Sindre Sorhus's guide on the topic: https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md
Have now figured what was wrong:
The directory had wrong permissions - it was not writable (which would have been a better error message than "accessible").
And because it was not writable, a temporary directory was used and deleted after every use, which is why the whole download had to run again and again.
The solution is to set user permissions with
sudo chown -R $USER <directory>
and never sudo npm again.
It seems whenever you run sudo npm, all subdirectories created get wrong permissions, which will lead to problems later on.
See here for more details.
Try with:
sudo npm install -g module --unsafe-perm
That's because you do not have a folder in this directory "/Users/dmitrizaitsev/.node-gyp/0.12.0".
Just create a new folder named 0.12.0 which is the version number of your node
It will fix the problem.

How can I install a Node.js module under $HOME/bin

The question title is self-expanatory, but just to make more clear...
With npm install -g I can install anything globaly, what turns it in an application command. But, in GNU/Linux, this requires root access, so, what if I want install something as a command, but only for the current logged user, and not needing root access?
Is that possible?
I haven't tried this, but according to the docs, you should be able to create a ~/.npmrc file with PREFIX=$HOME/bin
https://npmjs.org/doc/misc/npm-config.html
After #brian-glaz tip I managed to do like this:
Create a ~/.npmrc file with the folowing content
prefix=~/
Notice that it must be lowercase prefix.
You can check the paths as follows:
paulo.goncalves#paulogoncalves:~$ npm -g root
/home/paulo.goncalves/lib/node_modules
paulo.goncalves#paulogoncalves:~$ npm -g bin
/home/paulo.goncalves/bin

Resources