Maintaining a Private NPM registry for your Organization with Sinopia

Tweet about this on TwitterShare on LinkedIn7Share on Google+6Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

Maintaining a Private NPM registry with Sinopia

In this post, we will take a quick dig at setting up our own private Node Package Registry with Sinopia.

sinopia is a private/caching npm repository server

Maintaining a private NPM for your organization/team is very helpful when you would like to share the code only with them and not the entire universe. You can develop and maintain all your organization specific projects and their components as node packages that can be reused.

If there are multiple teams working, each of them can upload their own reusable node modules to the private NPM and other teams can use them. For example a File upload component or an organization specific HTML5 boilerplate and so on. This way, when you need something all you have to do is run npm install my-h5bp , which will download the boilerplate for you.

So, let us get started.

Official Approach

The folks at NPM have given us a process on how we can replicate the NPM privately.

Screen Shot 2014-09-21 at 10.16.33 amYou can check out this blog post to achieve the same. But this process is quite complex.

Another enterprise solution for setting up your private NPM is NPME – NPM Enterprise. You can find more info on that here : npm Enterprise. A quick video

Other Approaches

There are couple of other solutions like Kappa and node-reggie, which enable you to set up a private NPM with few quick steps.

But some how I was drawn to sinopia for its quick installation, setup and the ease of use. Sinopia uses a file system to manage the registry. The best part about Sinopia is, it does not sync the public registry by default, but it will cache the packages only when downloaded for the first time. You can save some space on your server (with the fast growing public registry and all).

Setup and Configure Sinopia

Setting up Sinopia as mentioned earlier is pretty easy. You need to have Node installed on the machine, where you are setting up the private NPM. Open terminal/prompt and  CD  to the root folder

Windows Mac/*nix
> cd /    $ cd ~

Inside the root directory, create a new directory named sinopia

mkdir sinopia && cd sinopia

Next, we will install sinopia globally. Run

npm install -g sinopia

(use sudo if needed)

Now, we will start the server run

sinopia

If you are launching the server for the first time, you will be asked to create a config file. Select Yes.

Note : If you launch the server from a different folder and if the folder does not have the config file you will be asked this question again. (I do not know why!) So make sure you launch the server from the same folder, the one we have cd ‘ed into earlier.

 

Screen Shot 2014-09-21 at 11.09.19 am

Now, when you navigate to http://localhost:4873/  you will see a message like

To enable the web interface, we need to tweak the config file. From the current folder, open the config.yaml file. Scroll to a section named the web and set enabled to true.

Screen Shot 2014-09-21 at 11.00.55 amKill the sinopia server and relaunch it. Now navigate to  http://localhost:4873  and you should see the web interface

Screen Shot 2014-09-21 at 11.02.35 amSweet right!!

[Important Step]

Now, from a client machine where the private NPM will be accessed from, you need to set the NPM registry URL pointing to our Private NPM server and not the public registry.

If your server and client are same, you can run

npm set registry http://localhost:4873

And if your server and client are on different machines, you need to run

npm set registry http://path.to.your.server:4873

In your config.yaml you can configure the host and port too. Navigate to the Advanced section and you can updated the config like

Screen Shot 2014-09-21 at 11.16.22 amKill sinopia and restart it. Now your web URL will be  http://localhost:2772. Reverting the port back to 4873, we will continue.

Setup User

By default there is an Admin user setup, which you can find under the users section in the config.yaml.

Screen Shot 2014-09-21 at 11.22.19 amThis is the default admin account and the sha1 encrypted password. I am not sure what this password is, so I will reset to admin$123.

For that, open a new terminal/prompt. Run node  then execute

crypto.createHash('sha1').update('admin$123').digest('hex') and paste it back to the config file

Screen Shot 2014-09-21 at 11.29.11 amSave the config file after pasting the generated hash, restart sinopia and run

Screen Shot 2014-09-21 at 11.34.59 amThe password would be admin$123.

You are logged in!!

To restrict access to the private registry, you can run

npm set always-auth true

This way you can secure all your private packages (more on conditional securing in a moment).

Now, a new client who would like to access the registry would need to create an account by running

npm adduser --registry http://localhost:4873/

Provide user details and bam!! You have a newly authenticated account for your private registry

Screen Shot 2014-09-21 at 11.48.24 am Now you will see a new file created inside the sinopia folder

The htpasswd file consists of the authentication data. It is better not to mess with this file.

Downloading packages

Now that we have everything setup, we will download our first package. Create a new folder named privateProj and open a new terminal/prompt inside this folder

Now run

npm init

to start a new node project. Next, we will install diskDB a node package for managing JSON files.  If you do notice your sinopia folder, you will see that there are only 2 files. The config and the htpasswd file. Now once we start pulling the packages, a new folder named storage will be created. You can configure the storage folder path in config.ymlScreen Shot 2014-09-21 at 11.59.23 am

From inside the privateProj run

npm install diskdb --save

And you should see

Screen Shot 2014-09-21 at 12.01.14 pmDo remember, diskdb is not in our private registry. Sinopia has fetched this package from the public repo. Now, if you see the sinopia folder, you will see

Screen Shot 2014-09-21 at 12.02.58 pmIf the public registry is offline or not available for some reason, sinopia will fetch the packages from the cache.  You can configure this behaviour in the uplinks section.

Screen Shot 2014-09-21 at 12.06.12 pmNow that we have diskdb installed in our privateProj, we will build a simple app and publish it to our private registry.

Build & Publish a Node module

You can check out my post Write your own Node Modules on how to create your own node modules and publish it.

Do note that as long as your registry URL is pointed to the private repo, the publish command would not save the package to the public registry.

Now, to build a sample node module/reusable component, we will create a folder named db and a file named app.js inside the privateProj folder.

Update the app.js as below

Now, our app is ready. We would like to share this app with our team, so they can reuse the printFruits().

For that we would be publishing this app to our private registry. Run

npm publish

and you should see something like

Screen Shot 2014-09-21 at 12.20.02 pmThe user arvind does not have access to publish to our private registry. For this to work, we need to provide access. Open config.yaml  and scroll down to the packages section and add the user name to allow_publish.Screen Shot 2014-09-21 at 12.23.18 pmSave the file and restart the sinopia server. Now when you publish you should see

Screen Shot 2014-09-21 at 12.25.16 pmAnd when you navigate to  http://localhost:4873 you should see

Screen Shot 2014-09-21 at 12.26.08 pm

Now, if you see the sinopia folder,

Screen Shot 2014-09-21 at 12.27.11 pm

Simple and easy right!!

Now, if someone wants to use your package all they need to do is run

npm install privateProj --save

The same way one would from the public registry and you should see

Screen Shot 2014-09-21 at 12.29.20 pm

And then in your project, you can directly use

And run

node myApp.js

If you want to maintain a different “namespace” for your private packages, you can do so by prefixing your packages with your organization name or your project name and update the config.yaml like

Screen Shot 2014-09-21 at 12.56.19 pm

You can also setup a different storage for your private repos too.

That is all you need to setup your private NPM and manage packages.

Note : If you followed the above post on a local machine and wanted to revert your npm registry to the public one, execute

npm config set registry https://registry.npmjs.org

or

npm config set registry http://registry.npmjs.org


Thanks for reading! Do comment.
@arvindr21

Tweet about this on TwitterShare on LinkedIn7Share on Google+6Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • Tom Dane

    So I should run npm login on the server or what ? What good will that do ? When I run it on the client it accepts whatever username/password. The article is good but need clarification of where you are running things, it’s impossible to figure out if you mean server or client.

  • Xander

    I thought love was only true in fairytales

  • Yair Zaslavsky

    Hi, I am running this on Ubuntu 14.0.x – seems like that “npm install -g” should be run with sudo privileges.
    Well it’s something that I assume most node users are aware to, but still I thought it’s worth mentioning.

    • Yair Zaslavsky

      Update: looks like “node” was pointing to some other utility on my machine, and I should have used nodejs.

      Since the other “node” utility was of less importance (also a soft link) I removed the soft link , and created a softlink of “node” to “nodejs” and now I managed to start the server.

    • Yair Zaslavsky

      Another update: by default the web interface is now enabled at the config.yaml file.