Npm is commonly used software registry and there’s a good chance that you’re already using it in your project. It allows you to install any of over 600,000 packages and to publish your own. Although it’s really popular and useful, there are few things you should consider when using it.

First of all, anyone can publish a package to npm, so many packages could lack in stability and/or quality, also the next release of a particular package may result in your failing build. Second concern is publishing your own packages. If you choose to use a free npm account, packages you’ve published will be available to the public.

If you are determined to keep your build stable and to publish your packages only for your own use, you may consider taking advantage of a private npm repository. In this example we’ll be using dockerized, open source version of Sonatype Nexus Repository Manager 3.

Kicking things off with Docker

Start with creating a new data volume on your docker machine, which will be dedicated to the docker container running Nexus. You can call it whatever you want, here we’re calling it nexus-data.

$ docker volume create --name nexus-data

Instead of creating a new data volume, you could mount a host directory as the volume, although this approach is not recommended. Details can be found here: Docker – Nexus3 Persistent Data.

Once you have your volume sorted out, you can create a docker container:

$ docker run -d -p 8081:8081 --name nexus -v nexus-data:/nexus-data sonatype/nexus3

This will fetch the latest sonatype/nexus3 docker image (assuming you don’t have this image locally) and run the docker container. Volume is specified after -v parameter: -v nexus-data:/volume_name.

You can provide additional parameters, for example add

-e NEXUS_CONTEXT=nexus_context_path

to change default Nexus Context Path from / to whatever you desire.

If you’d like to check whether Nexus server has started, try

$ curl -u admin:admin123 http://localhost:8081/service/metrics/ping

admin / admin123 are default credentials. You should get pong as a response. If you have changed Nexus Context Path or bound port different than 8081, remember to change it in curl as well.

Setting up npm repos

We need three kinds of repositories:

  • npm hosted – for npm packages published by you;
  • npm proxy – proxy to the global npm registry;
  • npm group – groups hosted and proxy repos.

Go to your Nexus Repository Manager, sign in and click the rack icon on the navbar to open server administration and configuration part. From the menu on the left pick „Repositories”.
Administration panel

Click „Create repository” and choose „npm (proxy)”.  Set „Name” field (for example npm-proxy) and set „Remote storage” to https://registry.npmjs.com. You can leave other properties with their default values.

Next, create „npm (hosted)” repository. Give it a name (for example npm-hosted) and leave other properties with their default values.

Lastly, add „npm (group)” repo. It needs a name (for example npm-group) and the other two repositories as „Members”:

Group repo members

Leave other properties as they are.

Npm configuration

Now that you have your repos created, we can move on to configuring npm in the project. Firstly, we need to read the auth token. We’ll do it for the default admin user, but if you’d like, you can create a new user and play around with giving him different privileges and roles.

Adding new user

For example, if you’d like to have a user who can consume packages kept on npm-proxy repo, but can’t add new packages, go to „Privileges” in the Administration menu and click „Create privilege”. Choose „Repository View” type, and fill in the form. Set „Name” to something that will distinguish this one from other privileges. Set „Format” to Node/npm, pick your npm-group repo as „Repository” and set read as „Actions”.

add new privilege

Nextly, go to „Roles” and create new role of type „Nexus role”. Set „Role ID” and „Role name” and pick created privilege in „Privileges” part.

add privileges to role

Finally, go to „Users” and click „Create local user”. Fill in all the required fields and assign created role.

create user

For more details on users and roles go to Nexus docs.

Carrying on with configuration

To get your admin’s base64 hash token, run:

$ echo -n admin:admin123 | openssl base64

Then, in the project’s root (this is where package.json is placed) edit, or create .npmrc file, if it doesn’t exist yet. Add following keys to the file:

registry=http://URL_to_your_npm_group_repo/
_auth=auth_token
email=your_email

„registry” key needs the URL to the group repo you’ve created, „_auth” will be the token you’ve read and „email” is your email address needed by npm publish. URL’s to all your repos can be found in the each repository’s „Settings” panel. Go to „Repositories” in the Administration menu, choose a repository from the list and read the address from the „URL” field.

Then, edit your package.json file, by adding

„publishConfig”: {

„registry”: „http://URL_to_your_npm_hosted_repo/”

}

Those changes will make every npm install command check for packages in your repo first, and if a package is not found, it will fetch the package and put it in your npm-proxy repo. Every npm publish will push your package to npm-hosted repo.

Big thanks to Rafael Eyng for this inspiring and helpful post.