Instalación de Verdaccio: Registro npm Privado
Verdaccio es un registro npm privado ligero que permite publicar, almacenar en caché y gestionar paquetes Node.js en tu propia infraestructura. Con soporte para proxy hacia el registro público de npm, control de acceso granular y despliegue sencillo con Docker, Verdaccio es la solución ideal para equipos que necesitan paquetes privados o una caché local para acelerar las instalaciones.
Requisitos Previos
- Servidor Linux (Ubuntu 20.04+, Debian 11+ o CentOS 8+)
- Node.js 18+ y npm (para instalación directa)
- Docker y Docker Compose (para instalación con Docker)
- Dominio o IP del servidor para el registro
- Acceso root o sudo
Instalación con npm
# Instalar Verdaccio globalmente
npm install -g verdaccio
# Verificar la instalación
verdaccio --version
# Iniciar Verdaccio (crea la configuración en ~/.config/verdaccio/)
verdaccio &
# Comprobar que está escuchando
curl http://localhost:4873/
Crea el servicio systemd para que Verdaccio arranque automáticamente:
# Crear usuario dedicado
sudo useradd -r -s /sbin/nologin verdaccio
sudo mkdir -p /opt/verdaccio/{storage,conf}
sudo chown -R verdaccio:verdaccio /opt/verdaccio
sudo tee /etc/systemd/system/verdaccio.service << 'EOF'
[Unit]
Description=Verdaccio - Registro npm Privado
After=network.target
[Service]
Type=simple
User=verdaccio
ExecStart=/usr/bin/verdaccio --config /opt/verdaccio/conf/config.yaml
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now verdaccio
Despliegue con Docker
Docker es la opción más rápida para entornos de producción:
# Crear estructura de directorios
mkdir -p /opt/verdaccio/{storage,conf,plugins}
# Configuración inicial
tee /opt/verdaccio/conf/config.yaml << 'EOF'
storage: /verdaccio/storage
auth:
htpasswd:
file: /verdaccio/conf/htpasswd
max_users: 50
uplinks:
npmjs:
url: https://registry.npmjs.org/
packages:
"@mi-empresa/*":
access: $authenticated
publish: $authenticated
unpublish: $authenticated
"**":
access: $all
publish: $authenticated
proxy: npmjs
server:
keepAliveTimeout: 60
middlewares:
audit:
enabled: true
log:
type: stdout
format: pretty
level: http
EOF
# Docker Compose
tee /opt/verdaccio/docker-compose.yml << 'EOF'
version: "3.8"
services:
verdaccio:
image: verdaccio/verdaccio:5
container_name: verdaccio
restart: unless-stopped
ports:
- "4873:4873"
environment:
- VERDACCIO_PORT=4873
volumes:
- ./storage:/verdaccio/storage
- ./conf:/verdaccio/conf
- ./plugins:/verdaccio/plugins
EOF
cd /opt/verdaccio && docker compose up -d
docker compose logs -f
Configura Nginx como proxy inverso con SSL:
sudo tee /etc/nginx/sites-available/verdaccio << 'EOF'
server {
listen 443 ssl http2;
server_name npm.tudominio.com;
ssl_certificate /etc/letsencrypt/live/npm.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/npm.tudominio.com/privkey.pem;
# Aumentar el tamaño para paquetes npm grandes
client_max_body_size 100m;
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-Proto $scheme;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/verdaccio \
/etc/nginx/sites-enabled/verdaccio
sudo certbot --nginx -d npm.tudominio.com
sudo systemctl reload nginx
Configuración del Proxy y Caché
Configura Verdaccio para usar caché agresiva de paquetes públicos:
# /opt/verdaccio/conf/config.yaml - Configuración de uplinks y caché
uplinks:
npmjs:
url: https://registry.npmjs.org/
cache: true # Almacenar paquetes en caché local
timeout: 30s
maxage: 10m # Tiempo de caché para metadatos
max_fails: 3 # Intentos antes de marcar como caído
fail_timeout: 5m
yarn:
url: https://registry.yarnpkg.com/
cache: true
packages:
# Paquetes privados de tu empresa - sin proxy a npm
"@mi-empresa/*":
access: $authenticated
publish: $authenticated
unpublish: $authenticated
# Alcance compartido con equipo externo
"@colaboracion/*":
access: $authenticated
publish: $authenticated
proxy: npmjs
# Todo lo demás se obtiene de npm y se almacena en caché
"**":
access: $all
publish: $authenticated
proxy: npmjs
# Configuración del servidor
server:
keepAliveTimeout: 60
# Retención de caché (limpiar paquetes sin usar después de N días)
store:
# Solo disponible con algunos plugins de almacenamiento
maxAge: 2592000 # 30 días en segundos
Publicación de Paquetes Privados
Configura npm para usar tu registro privado:
# Configurar npm para usar Verdaccio
npm set registry https://npm.tudominio.com/
# O usar un fichero .npmrc por proyecto
echo "registry=https://npm.tudominio.com/" > .npmrc
# Para paquetes con scope, solo redirigir ese scope a Verdaccio
echo "@mi-empresa:registry=https://npm.tudominio.com/" >> ~/.npmrc
# Crear una cuenta en Verdaccio
npm adduser --registry https://npm.tudominio.com/
# Iniciar sesión
npm login --registry https://npm.tudominio.com/
Publica tu paquete privado:
# Verificar que el package.json tiene el scope correcto
cat package.json | grep '"name"'
# Debe ser: "@mi-empresa/mi-paquete"
# Publicar el paquete
npm publish --registry https://npm.tudominio.com/
# Instalar desde el registro privado
npm install @mi-empresa/mi-paquete
# Verificar que el paquete está disponible
curl https://npm.tudominio.com/@mi-empresa%2fmi-paquete
Autenticación y Control de Acceso
Verdaccio usa htpasswd por defecto. Para gestionar usuarios:
# Instalar herramienta htpasswd
sudo apt install -y apache2-utils
# Añadir un nuevo usuario al fichero htpasswd
htpasswd /opt/verdaccio/conf/htpasswd nuevo_usuario
# Crear el fichero desde cero con el primer usuario
htpasswd -c /opt/verdaccio/conf/htpasswd admin
# Ver usuarios actuales
cat /opt/verdaccio/conf/htpasswd
Control de acceso granular en la configuración:
# Gestión detallada de acceso por paquete
packages:
# Paquetes críticos - solo el equipo de arquitectura puede publicar
"@mi-empresa/core-*":
access: $authenticated
publish: arquitectura desarrollo
unpublish: arquitectura
# Paquetes UI - cualquier desarrollador puede publicar
"@mi-empresa/ui-*":
access: $authenticated
publish: $authenticated
# Paquetes públicos - acceso sin autenticación
"utilidades-publicas":
access: $all
publish: $authenticated
proxy: npmjs
Integración con CI/CD
Configura tu pipeline para usar el registro privado:
# GitHub Actions / Gitea Actions
jobs:
build:
steps:
- name: Configurar npm para usar Verdaccio
run: |
echo "registry=https://npm.tudominio.com/" >> ~/.npmrc
echo "//npm.tudominio.com/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc
- name: Instalar dependencias
run: npm ci
- name: Publicar paquete
if: github.ref == 'refs/heads/main'
run: npm publish --registry https://npm.tudominio.com/
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Genera un token de autenticación para CI:
# Generar token npm para el pipeline
npm login --registry https://npm.tudominio.com/
# Introduce usuario, contraseña y email
# El token se guarda en ~/.npmrc - cópialo para los secretos del CI
grep "npm.tudominio.com" ~/.npmrc
# Resultado: //npm.tudominio.com/:_authToken=XXXXXXX
Solución de Problemas
Error 401 al publicar:
# Verificar que la sesión está activa
npm whoami --registry https://npm.tudominio.com/
# Volver a autenticarse
npm login --registry https://npm.tudominio.com/
# Comprobar permisos en la configuración de Verdaccio
grep -A5 "tu-paquete" /opt/verdaccio/conf/config.yaml
Verdaccio no hace proxy a npm:
# Verificar conectividad desde el servidor
curl https://registry.npmjs.org/express
# Ver los logs de Verdaccio
docker compose logs verdaccio | grep -i error
# Probar el uplink manualmente
curl https://npm.tudominio.com/express
Paquetes no se actualizan (caché obsoleta):
# Forzar la actualización del paquete en caché
npm install paquete@latest --registry https://npm.tudominio.com/ --force
# Limpiar el almacenamiento de un paquete específico
rm -rf /opt/verdaccio/storage/nombre-del-paquete
Conclusión
Verdaccio proporciona un registro npm privado completo que combina almacenamiento de paquetes internos con caché transparente del registro público. Su configuración sencilla, control de acceso granular y compatibilidad con los flujos de trabajo estándar de npm lo convierten en la solución perfecta para equipos que desarrollan con Node.js y necesitan privacidad, velocidad o control sobre sus dependencias.


