node-forward / help

Need help with Node? You've come to the right place! Log an issue.
http://nodeforward.org/
47 stars 5 forks source link

How to install Node to avoid sudo #4

Open KatieK2 opened 9 years ago

KatieK2 commented 9 years ago

What's the best way to install Node to allow packages the permissions they need to install, and to avoid having to sudo every package install?

It seems like very install process I use results in having to sudo install whatevs which is a security anti-pattern. How can I install sanely on my development machine?

aredridel commented 9 years ago

As far as anti-patterns go, npm actually does some clever things. It runs installation scripts as a non-root user; it's actually more secure from some attacks (malicious package scripts) when run as root because of this, because it can call setuid.

However, the isolation of not needing to run as root is good for other reasons, too.

You can install node and npm to some place that does not require root access to write to. On a Mac, for a single user, chown -R $USER /usr/local works nicely.

Making your own private place to install to and adding it to your $PATH is also a great way to go:

cd ~
tar xzf node-v0.10.32-linux-x64.tar.gz
PATH="$HOME/node-v0.10.32/bin:$PATH"

And then there are tools like nvm which automate this and put it in a version-neutral place, so upgrades don't shake it all apart.

othiym23 commented 9 years ago

I can't wait until somebody asks this question about Windows; the answer is a nightmare. ;)

I personally follow Aria's suggestion (which is also how Homebrew on OS X wants me to have /usr/local configured – and I run brew doctor periodically to ensure that nothing has broken since the last time I looked). The simplest way to avoid permissions issues to avoid putting yourself in situations where they're relevant. As far as I can tell, this is the official npm recommendation as well.

It's true that npm tries to do the right thing when run as root, but it's also true that we've had to fix some bugs because npm didn't quite get things right. Right now, for instance, there's a bug (npm/npm#6548) that will cause a piece of the npm cache's internal machinery to get created with the wrong permissions when you install a git dependency for the first time as root. There have been others, some of which have been addressed relatively recently. I don't see these bugs, because I'm always running npm with regular privileges, so if you do things the same way that the npm developers do, you will have fewer problems as well. :tada: (This is not actually a good argument.)

A little historical context

From time to time, somebody will put together a Stack Overflow answer or a blog post showing how you can set up npm to use a subfolder of your home directory as its global location, and while you can do that, it's not the path of least resistance. @isaacs designed npm to put global scripts in /usr/local/bin, and installing to /usr/local/lib/node_modules follows from that decision. It's easier for most people to understand, and the trend, at least with OS X developer machines and servers in the clown, is for most hosts to be single-user, where it makes sense for that single user to have write permissions to /usr/local.

upshot

So:

  1. change /usr/local to be writable by your normal user account, or
  2. use a version manager like nvm that installs global packages to a per-user prefix, or
  3. use sudo and clean things up periodically

One final recommendation: never run a local install (i.e. npm install without -g) as root. If your deployment strategy requires this, fix your deployment strategy. Also (and this is somewhat counter to what npm does in some cases), don't use nobody to own files. The whole point of nobody is that it doesn't own anything.

othiym23 commented 9 years ago

(It's bad for nobody to own files because on unix systems, that account is meant to have the least privileges possible. When a service running as nobody is compromised, you don't want it to be able to alter, delete, or even read any of the files on the compromised system.)

arb commented 9 years ago

Got this idea from this SO question. Basically use npm config set prefix ~/npm to tell npm to put global modules there and add that location to your $PATH variable. I've done it that way ever since and do not need to sudo anything.

darrenderidder commented 9 years ago

@KatieK2 If you need executable scripts in a unix (linux/mac) environment you can export PATH=$PATH:./node_modules/.bin. It allows you for example to run things like mocha from the local project directory instead of having to use npm -g install all the time. Here's short post on that. Hope that helps!

othiym23 commented 9 years ago

@darrenderidder A few developers at npm follow that pattern, but I don't, for the same reason that I don't add . to my PATH – it's very easy to inadvertently run something you shouldn't that way. I think I prefer using a version manager like nave or nvm or configuring prefix to be $HOME/npm (or something similar).

aredridel commented 9 years ago

Yeah. I'm torn on it; I add it to mine, but I'm very careful and not on a multi-user system. It's a clever hack, but I'd love to see npm have an exec command that'd run things with ./node_modules/.bin/ in the path.

darrenderidder commented 9 years ago

Well, the docs specify ./node_modules/.bin for local executables , so I find it convenient to have in $PATH. It's optional - npm kindly adds ./node_modules/.bin/whatever to your $PATH for executable dependencies that you invoke as npm scripts (docs). I found sudo was mostly necessary because of using npm -g to install things globally, but I'm pretty sure it's been a couple of years since that was the recommended way.

aredridel commented 9 years ago

Yup. Just gotta be careful if you cd into a random repository that's not yours, that means someone could make an innocuous command like, say, ls run something you don't expect.

MylesBorins commented 9 years ago

Npm scripts already do this!

One trick I have been doing lately is to design modules that export binaries, installing them as dev dependencies, and just using npm scripts to call them. On Nov 15, 2014 8:25 PM, "Aria Stewart" notifications@github.com wrote:

Yeah. I'm torn on it; I add it to mine, but I'm very careful and not on a multi-user system. It's a clever hack, but I'd love to see npm have an exec command that'd run things with ./node_modules/.bin/ in the path.

— Reply to this email directly or view it on GitHub https://github.com/node-forward/help/issues/4#issuecomment-63203745.

darrenderidder commented 9 years ago

@aredridel Agree, although ./ is kind of another discussion; some devs add it at the end ie. PATH=$PATH:./ for the reason you said, so commands don't get overridden unexpectedly...

imlucas commented 9 years ago

@othiym23 not sure if this is the right repo to post this, but really interested in the install/introduction problem. I've been kicking an idea around for a bit now and am curious what other folks think.

What if we had a installno.de to point to? Braindump ways to address common problems and scenarios I've dealt with in this area:

Somebody told me to install node.js on my macbook

I want to install and manage node with my package manager

I made a node module

shime commented 9 years ago

@imlucas I love the idea. it would be great to have installation instructions available on a rememberable URL like that, since nodejs.org currently just links to compressed build, which is not very beginner-friendly. count me in if you need help.

also, maybe opening up a separate issue for this would be a good idea, since this issue is only about avoiding sudo.

linclark commented 9 years ago

I'm currently working on documenting this for npm, npm/docs.npmjs.com#48