Howto publish private projects to Sinopia (npm adduser for private registry fails)

cdanea picture cdanea · Mar 25, 2014 · Viewed 28.5k times · Source

Ok so I finally managed to get a private npm registry using Sinopia. But I cannot publish anything to it.

TL;DR: Sinopia does not support npm adduser, but has its own user management. Also npm needs a valid user created before npm publish through npm adduser, which fails because the internal Sinopia server throws an error at the unsupported command....

How does one use Sinopia as a private registry with proper users and passwords

  1. create a global user in npmjs.org, and then another with the same password in Sinopia?
  2. Or is there an easier way to tell npm to just use a fixed user/pass.
  3. Or even better prompt me somehow for username and password?
  4. something else?

Synopsis:

Sinopia does not depend on Couch.DB and will hapilly fetch packages it does not already have from a master (default is the global npmjs.org).

Sinopia starts perfectly and is configured to listen on all interfaces. It works wonders in serving packages to

npm install

I even configured ~/.npmrc to always point to the internal registry.

All projects' package.json file is set to

  ....
  "publishConfig" : {
     "registry" : "http://internal-npm:4873"
  },
  ....

Also I managed to add custom users in sinopia by manipulating the config.yaml with the help of js-yaml

crypto.createHash('sha1').update('theBigPassword').digest('hex')

Now I am stuck at

npm --registry=http://internal-npm:4873 --ca=null publish

After a long wait I get:

npm ERR! need auth auth and email required for publishing
npm ERR! need auth You need to authorize this machine using `npm adduser`

npm ERR! System Linux 3.11.0-18-generic
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "--registry=http://internal-npm:4873" "--ca=null" "publish"
npm ERR! cwd /home/ciprian/workspace/netop-npm
npm ERR! node -v v0.10.15
npm ERR! npm -v 1.2.18
npm ERR! code ENEEDAUTH
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/ciprian/workspace/netop-npm/npm-debug.log
npm ERR! not ok code 0

The business end of the log file tells me that the user is not optional

86 error need auth auth and email required for publishing
86 error need auth You need to authorize this machine using `npm adduser`
87 error System Linux 3.11.0-18-generic
88 error command "/usr/bin/nodejs" "/usr/bin/npm" "--registry=http://internal-npm:4873" "--ca=null" "publish"
89 error cwd /home/ciprian/workspace/netop-npm
90 error node -v v0.10.15
91 error npm -v 1.2.18
92 error code ENEEDAUTH
93 verbose exit [ 1, true ]

Now, the chicken and egg issue is that Sinopia does not support npm adduser, but has its own user management like I mentioned above. Also npm needs a valid user created through npm adduser, which fails because the internal Sinopia server throws an error at the unsupported command.

Answer

alex picture alex · Mar 28, 2014

First of all, it is not "chicken and egg" problem.

"npm adduser" does two things:

  1. it creates a new user on the remote server, or verifies that it exists
  2. it adds _auth to your .npmrc

Sinopia will complain if user doesn't exist, but if it does, it'll happily report success.


So, what you have to do is this:

  1. add user/pass to config.yaml (see josh's answer) and restart sinopia server
  2. run npm adduser --registry http://internal-npm:4873/

Yes, "adduser" command is confusing, because it won't actually add a new user. It'll just verify that user exists in config.

If you want, you can use "npm login" command. It is less confusing even though it does exactly the same thing. :)


Second of all, add this to your package.json:

"publishConfig": {
  "registry": "http://internal-npm:4873/"
}

This way npm won't publish it to the public registry anymore, even if it's a default one.


And lastly, you can't use two registries (npmjs and your private one) at the same time with the same npmrc. It's even less secure than you think.

It's okay in most cases, but if you have to use both of them (for example, you maintain public and private packages at the same time), use yapm instead of npm and write something like this to your .npmrc:

[registries."https://registry.npmjs.org/"]
_auth = (your auth string for public registry)

[registries."http://internal-npm:4873/"]
_auth = (your auth string for private registry)
always-auth = true

It'll prevent exposing your passwords to public registry in all cases.