How to Create a Self-Hosted Package Registry with Verdaccio
Verdaccio is a lightweight, open-source npm registry proxy that lets you host private packages and cache public packages locally. Running Verdaccio on your Breeze server speeds up installs and gives you complete control over your JavaScript dependencies.
Why Self-Host a Package Registry
- Private packages — publish internal libraries without exposing them publicly
- Offline resilience — cached packages remain available during upstream outages
- Faster installs — local cache eliminates repeated downloads from external registries
- Security — audit and control which packages are available to your team
Installing Verdaccio with Docker
docker run -d --name verdaccio \
-p 4873:4873 \
-v verdaccio_data:/verdaccio/storage \
-v verdaccio_conf:/verdaccio/conf \
verdaccio/verdaccio:latest
Docker Compose Setup
For a production deployment on your Breeze instance:
services:
verdaccio:
image: verdaccio/verdaccio:latest
ports:
- "4873:4873"
volumes:
- ./verdaccio/config:/verdaccio/conf
- ./verdaccio/storage:/verdaccio/storage
- ./verdaccio/plugins:/verdaccio/plugins
environment:
VERDACCIO_PORT: 4873
restart: unless-stopped
volumes:
verdaccio_storage:
Configuring Verdaccio
Edit the configuration file at ./verdaccio/config/config.yaml:
storage: /verdaccio/storage/data
auth:
htpasswd:
file: /verdaccio/storage/htpasswd
max_users: 100
uplinks:
npmjs:
url: https://registry.npmjs.org/
cache: true
packages:
'@mycompany/*':
access: $authenticated
publish: $authenticated
unpublish: $authenticated
'**':
access: $all
publish: $authenticated
proxy: npmjs
middlewares:
audit:
enabled: true
listen: 0.0.0.0:4873
Using Verdaccio as Your Registry
Configure npm or yarn to use your Verdaccio instance:
# Set the registry globally
npm set registry http://your-breeze-ip:4873
# Or per project with .npmrc
echo "registry=http://your-breeze-ip:4873" > .npmrc
# Create a user account
npm adduser --registry http://your-breeze-ip:4873
# Publish a private package
npm publish --registry http://your-breeze-ip:4873
Publishing Private Packages
Scope your private packages with your organization name:
{
"name": "@mycompany/shared-utils",
"version": "1.0.0",
"private": false,
"publishConfig": {
"registry": "http://your-breeze-ip:4873"
}
}
Adding HTTPS with a Reverse Proxy
Place Verdaccio behind Nginx with SSL for production use:
server {
listen 443 ssl;
server_name npm.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/npm.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/npm.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:4873;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Best Practices
- Enable HTTPS in production to protect authentication tokens
- Use scoped packages (
@mycompany/) for private libraries - Set up automated backups of the storage directory
- Monitor disk usage as cached packages accumulate over time
- Configure
max_usersto prevent unauthorized signups
Verdaccio running on your Breeze server gives your team a reliable, private npm registry that is fast and fully under your control.