自建私有npm仓库

在国内下载npm包,rpm包等各种包都非常慢,有时候好不容易成功一次,等第二次新的工程需要时就又得在耗费一些时间了。因此有一个自己仓库非常重要,能提升不少的开发效率。

我们需要一个这样的npm仓库来满足我们的需求:

  1. 当我们运行npm install需要安装一些依赖包时,它会先在自己的服务器上寻找,找不到时,在上官方的仓库寻找。
  2. 这个服务器能够根据请求,自动的把自己没有一些包存储在自己的服务器内部。等用户再发生同样请求时能够,此服务器能够用自己的包来响应请求,而不是从官方查找。
  3. 我们能够向该服务器发布自己的私有包。

经过一番调研,我们发现nexus3项目就非常符合我们的需求。它还提供docker image安装,非常方便。这是github地址:

https://github.com/sonatype/docker-nexus3

参照它的方法我们只需要执行:
docker run -d -p 8081:8081 --name nexus sonatype/nexus3

即可运行nexus3服务器。nexus3是专业的仓库服务器,除了npm还支持docker, deb, rpm ,maven等仓库的建设。对每种仓库源,nexus3基本都支持3种类型。hosted, group和proxy。proxy就是仓库代理,它支持我上面提到对仓库的需求。具体的如何配置npm仓库可以参照下文:

Configuring Nexus as a npm repo

What we will do:
– create a private (hosted) repository for our own packages
– create a proxy repository pointing to the official registry
– create a group repository to provide all the above repos under a single URL

I suggest you to create a new blob store for each new repo you want to create. That way, the data for every repo will be in a different folder in /nexus-data (inside the Docker container). But this is not mandatory for it to work.

private repo

A repository for npm packages that your team develops.

Create a new npm (hosted) repository and configure it like:

Using Nexus 3 as Repo - 1.png

The deployment policy “Allow redeploy” above might look somewhat polemic, so you might want to set it to “Disable redeploy”. In my use case, it makes sense to use “Allow redeploy”, since we keep a latest version on Nexus always updated with the status of the master branch, that is redeployed in our CI flow.

proxy repo

A repository that proxies everything you download from the official npm registry. Next time you download the same dependency, it will be cached in your Nexus.

Create a new npm (proxy) repository and configure it like:

Using Nexus 3 as Repo. - 3.png
Using Nexus 3 as Repo - 2.png

group repo

This will group all the above repos and provide you a single URL to configure your clients to download from/deploy to.

Create a new npm (group) repository and configure it like:

Using Nexus 3 as Repo - 4.png

You can create as many repos as you need and group them all in the group repo, but for npm I don’t think that you will need more than 1 proxy and 1 private repos.

Configuring your clients and projects to use your Nexus repos

For npm, we will configure the repository per project (unlike Maven, that have some global configs, for instance). I believe that you can configure the authentication globally in your machine, with npm addUser, but I didn’t went that way for simplicity.

If you have a project where you only want to download dependencies from Nexus, create a .npmrc file at your project’s root with:

registry=http://your-host:8081/repository/npm-group/
_auth=YWRtaW46YWRtaW4xMjM=

_auth=YWRtaW46YWRtaW4xMjM= is the base64 hash for the credentials (admin/admin123). If you use a different set of credentials, you should compute your own hash with:

echo -n 'myuser:mypassword' | openssl base64

You have to set a user so you can publish packages. If you do this from your local machine, npm publish will use your user configured in ~/.npmrc (in your home, not in your project). If you don’t have this configuration, or if you want to publish from CI, you can set an email=any@email.com configuration in your project’s .npmrc. Really, any email.

If you have a project that you want to publish to your Nexus, put this in package.json:

{
  ...

  "publishConfig": {
    "registry": "http://your-host:8081/repository/npm-private/"
  }
}

Note that you publish to your private repo, but when you download, you can point to your group repo, so both your own packages and the packages from the official repo will be available from a single URL.

Now if you run in your projects:

npm install
# or
npm publish

your npm will point to your Nexus instance.

Installing npm packages globally

Run:

npm --registry http://your-host:8081/repository/npm-group/ install -g your-pac