Backend Development 17 min read

Step‑by‑Step Guide to Building an Enterprise‑Grade Private npm Registry

This guide explains why and how to set up an enterprise‑grade private npm registry using cnpmjs.org, covering prerequisites, installation, configuration, database setup, nginx proxying, security considerations, process management with pm2, and optional cloud storage extensions.

政采云技术
政采云技术
政采云技术
Step‑by‑Step Guide to Building an Enterprise‑Grade Private npm Registry

Introduction

npm is an essential package manager for front‑end and full‑stack developers. While public registries like https://registry.npmjs.org/ are convenient, many companies need a private npm registry for stability, confidentiality, and security. This article shows how to build an enterprise‑level private npm registry in minutes.

Why Build a Private npm Registry?

Stability : Own infrastructure ensures network and resource reliability, avoiding downtime or accidental removal of critical packages.

Confidentiality : Internal modules or customized forks stay within the company and are not published to public registries.

Security : Private registries allow you to audit packages and prevent malicious code.

How to Build a Private npm Registry

We use the open‑source solution cnpmjs.org (https://www.npmjs.com/package/cnpmjs.org) because it is widely adopted in large Chinese companies and offers strong extensibility and configurable options.

Prerequisites

Linux server (Ubuntu is used in the example)

Node.js environment

MySQL database

nginx for reverse proxy

Installation

Clone the source code: git clone https://github.com/cnpm/cnpmjs.org.git

Install project dependencies: npm i

Edit config/index.js (only a few key fields are needed for a basic setup): Service ports: registryPort: 7001, // registry service port webPort: 7002, // web UI port bindingHost: '' // leave empty for internal use, comment out for external access Database configuration (example uses MySQL): database: { db: 'npm', username: 'admin', password: 'admin123', dialect: 'mysql', host: '127.0.0.1', port: 3306, pool: { maxConnections: 10, minConnections: 0, maxIdleTime: 30000 } } Enable private mode (default false ): enablePrivate: false, Scope prefix for non‑private mode: scopes: ['@catfly'], Administrator accounts: admins: { fengmk2: '[email protected]', admin: '[email protected]', dead_horse: '[email protected]' } Sync model (choose 'exist' to sync only packages already in the database): syncModel: 'exist'

Database setup: Start MySQL and create the database: mysql -u root -p test123456 create database npm; Run the provided script docs/db.sql to create tables: source docs/db.sql;

Start the service: npm run start

nginx Reverse Proxy

If the server is exposed to the internet, hide the internal ports behind nginx. Create /etc/nginx/conf.d/npm.conf :

server {
  listen 80;
  server_name www.mirrors.catfly.vip;
  location / {
    proxy_pass http://127.0.0.1:7002/; # web UI
    proxy_set_header X-Real-IP $remote_addr;
  }
  location /registry/ {
    proxy_pass http://127.0.0.1:7001/; # registry API
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Restart nginx and open the firewall or security‑group ports (7001, 7002) as needed.

Verification

Install nrm to switch npm sources:

npm i nrm -g
nrm add catfly http://www.mirrors.catfly.vip/registry
nrm use catfly

Register a user, log in, and publish a private package:

npm adduser
npm login
npm publish

After publishing, you can install the package with npm i <package> and view the web UI at http://www.mirrors.catfly.vip/ .

Extended Topics

Process Management with pm2

Install pm2 globally and start the cnpmjs.org dispatcher:

npm i pm2 -g
pm2 start ./dispatch.js # dispatch.js is in the project root
pm2 monit dispatch

pm2 provides multi‑process management, monitoring, load balancing, and automatic restarts.

Storing Packages in the Cloud

cnpmjs.org supports custom NFS modules. Replace the default fs-cnpm with a cloud storage plugin such as oss-cnpm (Alibaba Cloud OSS):

cnpm i oss-cnpm
var oss = require('oss-cnpm');
var nfs = oss.create({
  accessKeyId: 'xxxx',
  accessKeySecret: 'xxx',
  endpoint: 'oss-cn-beijing.aliyuncs.com',
  bucket: 'catfly-xxx',
  mode: 'private'
});
var config = { ..., nfs: nfs, ... };

After restarting the service, all uploaded packages are stored in the OSS bucket instead of the local /root/.cnpmjs.org/downloads/ directory.

References

PM2 usage guide: https://segmentfault.com/a/1190000002539204

Deploying and customizing CNPM – custom storage layer: https://www.v2ex.com/t/294255

backendDeploymentnginxnpmcnpmjspm2private-registry
政采云技术
Written by

政采云技术

ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.