Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to install Node to avoid sudo #4

Open
KatieK2 opened this issue Oct 26, 2014 · 14 comments
Open

How to install Node to avoid sudo #4

KatieK2 opened this issue Oct 26, 2014 · 14 comments

Comments

@KatieK2
Copy link

KatieK2 commented Oct 26, 2014

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
Copy link

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
Copy link
Contributor

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. 🎉 (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
Copy link
Contributor

(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
Copy link

arb commented Oct 29, 2014

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
Copy link

@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
Copy link
Contributor

@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
Copy link

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
Copy link

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
Copy link

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
Copy link

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
#4 (comment).

@darrenderidder
Copy link

@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
Copy link

imlucas commented Nov 17, 2014

@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

  • auto-detect platform to download a binary like node.js
  • less religion/marketing talk than .org that explains in two sentences node, npm and their practical applications
  • current .org copy is "Node.js® is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications." and 9/10 people I send to that page immediately glaze over causing them to miss the big "download" button

I want to install and manage node with my package manager

  • snippets flow
  • markdown badge/snippet to drop into README's
    • "osx" -> homebrew and co.

I made a node module

  • rather than not mentioning node.js at all, or even worse providing misinformation, give me a snippet that explains like two sentences from above ("This is a module for node.js XXXX") and a badge that links to installno.de
  • badge has reference to repo url like heroku deploy button that provides extra context on install page like:
    • "You're using OSX and the module has leveldb in it's dependencies" -> now mention xcode requirements/steps not as the first sentence :)
    • "express in it's dependencies" -> tell me what express means and give me links for info as the project's README is most likely full of assumptions that I know what "express" means

@shime
Copy link

shime commented Nov 20, 2014

@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
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants