|
|
||
|---|---|---|
| .. | ||
| config | ||
| app.manifest.yaml | ||
| CHANGES.md | ||
| DEPLOY.md | ||
| docker-compose.yml | ||
| INSTALL.sh | ||
| README.md | ||
Verdaccio - Hybrid NPM Cache
Purpose: Cache public npm packages + mirror @lilith/* from Forgejo Location: black server (10.0.0.11) via VPN Access: http://npm.nasty.sh:4873/ (VPN-only) Storage: /bigdisk/verdaccio/storage/
Architecture
Package Resolution Flow
Developer/CI → npm install <package>
↓
Verdaccio (npm.nasty.sh:4873)
├─ @lilith/* → Proxy to forge.nasty.sh (2h cache)
└─ Public → Cache from npmjs.org (7d cache)
Publishing Flow
Developer → npm publish @lilith/package
↓
publishConfig in package.json → forge.nasty.sh (unchanged)
↓
Verdaccio mirrors from forge (auto-update within 2h)
Key principle: Verdaccio is consumption-only. Publishing still targets forge.nasty.sh.
Quick Start
Deploy to Black
# From lilith-platform directory
scp -r deployments/docker/verdaccio black:/bigdisk/
ssh black
cd /bigdisk/verdaccio
docker-compose up -d
Check Status
ssh black "docker ps | grep verdaccio"
# Or
curl http://npm.nasty.sh:4873/-/ping
# Expected: {}
View Logs
ssh black "cd /bigdisk/verdaccio && docker-compose logs -f"
First-Time Setup
1. Create Admin User
ssh black
cd /bigdisk/verdaccio/config
# Create htpasswd file
htpasswd -Bc htpasswd lilith
# Enter password when prompted
# Restart Verdaccio
cd /bigdisk/verdaccio
docker-compose restart
2. Update Forgejo Nginx
Add to /bigdisk/forgejo/nginx.conf:
# Verdaccio upstream
upstream verdaccio {
server verdaccio:4873;
}
# npm.nasty.sh - Verdaccio NPM Cache
server {
listen 80;
server_name npm.nasty.sh;
# VPN-only access
allow 10.0.0.0/24; # LAN
allow 10.9.0.0/24; # VPN
deny all;
client_max_body_size 100M;
location / {
proxy_pass http://verdaccio;
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;
# Disable buffering for npm publish
proxy_buffering off;
proxy_request_buffering off;
# Timeouts for large packages
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
}
Reload nginx:
ssh black "docker exec forgejo-nginx nginx -t"
ssh black "docker exec forgejo-nginx nginx -s reload"
3. Add DNS Entry
# Via PowerDNS
pdnsutil add-record nasty.sh npm A 10.0.0.11
# Or add to /etc/hosts
echo "10.0.0.11 npm.nasty.sh" | sudo tee -a /etc/hosts
4. Test Access
curl http://npm.nasty.sh:4873/-/ping
# Expected: {}
# Web UI
curl -I http://npm.nasty.sh:4873/
# Expected: 200 OK
Client Configuration
For Developers
Update ~/.npmrc:
# Verdaccio for consumption
@lilith:registry=http://npm.nasty.sh:4873/
# Auth for Verdaccio (reuse Forgejo token)
//npm.nasty.sh:4873/:_authToken=${FORGEJO_NPM_TOKEN}
# Forge auth (still needed for publishing)
//forge.nasty.sh/api/packages/lilith/npm/:_authToken=${FORGEJO_NPM_TOKEN}
Login to Verdaccio
npm adduser --registry=http://npm.nasty.sh:4873/
# Username: lilith (or created via htpasswd)
# Password: <password from htpasswd>
# Email: your@email.com
Test Installation
# Public package (caches from npmjs.org)
npm install react --registry=http://npm.nasty.sh:4873/
# @lilith/* package (proxies to forge)
npm install @lilith/ui-theme --registry=http://npm.nasty.sh:4873/
Publishing (Unchanged)
cd ~/Code/@packages/@ui/ui-theme
npm version patch
npm publish # Uses publishConfig → forge.nasty.sh
Troubleshooting
Container Won't Start
# Check logs
ssh black "cd /bigdisk/verdaccio && docker-compose logs"
# Check network
ssh black "docker network ls | grep forgejo"
Cannot Access Web UI
-
Check nginx config:
ssh black "docker exec forgejo-nginx nginx -t" -
Check DNS:
dig npm.nasty.sh +short # Expected: 10.0.0.11 -
Check firewall (should allow port 80 from VPN):
ssh black "sudo ufw status"
Package Install Fails
-
Check Verdaccio health:
curl http://npm.nasty.sh:4873/-/ping -
Check auth:
npm whoami --registry=http://npm.nasty.sh:4873/ -
Check uplink connectivity:
# From black server ssh black "docker exec verdaccio wget -q -O- http://forge.nasty.sh/api/packages/lilith/npm/" ssh black "docker exec verdaccio wget -q -O- https://registry.npmjs.org/react"
Publishing Fails
Expected behavior: Publishing should target forge.nasty.sh, not Verdaccio.
Verify publishConfig in package.json:
{
"publishConfig": {
"registry": "http://forge.nasty.sh/api/packages/lilith/npm/"
}
}
If accidentally published to Verdaccio, unpublish:
npm unpublish @lilith/package@version --registry=http://npm.nasty.sh:4873/
Maintenance
Update Verdaccio
ssh black
cd /bigdisk/verdaccio
docker-compose pull
docker-compose up -d
Add User
ssh black
cd /bigdisk/verdaccio/config
htpasswd -b htpasswd <username> <password>
cd /bigdisk/verdaccio
docker-compose restart
Check Disk Usage
ssh black "du -sh /bigdisk/verdaccio/storage"
ssh black "du -sh /bigdisk/verdaccio/storage/* | sort -rh | head -20"
Clear Cache (Package-Specific)
ssh black
rm -rf /bigdisk/verdaccio/storage/@lilith/package-name
docker-compose restart verdaccio
Backup Storage
ssh black
tar -czf verdaccio-backup-$(date +%Y%m%d).tar.gz /bigdisk/verdaccio/storage/
Performance Metrics
Expected Improvements
- First build after cache: No change (downloads from upstream)
- Subsequent builds: 20-40% faster (LAN vs internet)
- CI parallel builds: Significant improvement (shared cache)
Storage Estimates
- @lilith/ packages*: ~35MB (69 packages, metadata only)
- Public packages: ~2-4GB after 30 days
- Growth rate: ~1GB/month
Monitoring
# Cache hit rate (approximate)
ssh black "grep 'cache: hit' /var/log/docker/verdaccio.log | wc -l"
# Package count
ssh black "find /bigdisk/verdaccio/storage -name 'package.json' | wc -l"
# Top packages by size
ssh black "du -sh /bigdisk/verdaccio/storage/* | sort -rh | head -20"
Security Notes
- VPN-only access: npm.nasty.sh resolves to 10.0.0.11 (LAN/VPN only)
- No internet exposure: Nginx restricts to 10.0.0.0/24 and 10.9.0.0/24
- Authentication: htpasswd file (bcrypt hashed)
- Upstream auth: Proxies to forge use forge credentials (configured in uplink)
References
- Verdaccio Docs: https://verdaccio.org/docs/configuration
- Docker Image: https://hub.docker.com/r/verdaccio/verdaccio
- Plan:
/var/home/lilith/.claude/plans/greedy-floating-hollerith.md - Port Registry:
deployments/ports.yaml(verdaccio: 4873)
Last Updated: 2026-01-11 Deployed: black (10.0.0.11) Status: Production-ready