Deploy Verdaccio on Ubuntu — lightweight self-hosted private npm registry with proxy to npmjs.org, scoped packages, and zero Java dependency.
Grab the automated bash script from GitHub to follow along with the video.
wget https://raw.githubusercontent.com/mhmdali94/Docker/main/dev/verdaccio/verdaccio-ubuntu.sh
chmod +x verdaccio-ubuntu.sh
sudo bash verdaccio-ubuntu.sh
wget https://raw.githubusercontent.com/mhmdali94/Docker/main/dev/verdaccio/verdaccio-ubuntu.sh
chmod +x verdaccio-ubuntu.sh
The script installs Docker if needed, then sets up the service automatically.
sudo bash verdaccio-ubuntu.sh
Open your browser and navigate to:
http://<your-server-ip>:4873
Point npm to your Verdaccio registry, create a user account, and publish your first package.
# Point npm to your Verdaccio registry
npm set registry http://<your-server-ip>:4873
# Create a user account
npm adduser --registry http://<your-server-ip>:4873
# Publish a package
npm publish --registry http://<your-server-ip>:4873
# Install packages (falls back to npmjs.org automatically)
npm install lodash
| Port | Purpose |
|---|---|
| 4873 | Verdaccio npm Registry |
Verdaccio is a lightweight, open-source private npm registry that runs as a single Node.js process in Docker. It acts as a proxy to the public npmjs.org registry (packages not found locally are fetched and cached automatically), while also hosting your private packages that you publish with npm publish. Unlike Nexus or Artifactory, Verdaccio needs no Java, no complex configuration, and minimal RAM — it starts in seconds and uses a simple YAML configuration file. It is ideal for teams that publish internal npm packages and want to avoid the costs and complexity of npm Pro or a full artifact manager.
Publishing internal packages to the public npm registry exposes your code and leaks internal naming conventions. Verdaccio gives you a private namespace for packages like @yourcompany/utils without any public visibility. The proxy feature means developers never notice the difference — npm install works as normal, fetching public packages through Verdaccio's cache and private packages from your hosted registry. This also enables fully air-gapped builds where no internet access is needed after the initial cache warm-up.
Verdaccio listens on port 4873 by default. For team use, proxy it through Nginx Proxy Manager with HTTPS and a custom domain (e.g. npm.yourdomain.com). Developers and CI jobs point their .npmrc at the HTTPS domain, not the raw port. No other ports are needed — Verdaccio has no database or separate backend process.
Nexus Repository OSS (supports npm, Maven, Docker, PyPI — far more powerful, requires 4 GB RAM and Java knowledge), Gitea Packages (built into Gitea if you already use it — no extra server), npm Enterprise (official private registry, paid SaaS). Verdaccio is the right choice when you only need a private npm registry and want the simplest possible setup with minimal resources.
Skip Verdaccio if you also need to host Docker images, Maven artifacts, or PyPI packages — use Nexus Repository instead. Also skip it if your team already uses Gitea, which includes a built-in package registry that supports npm without a separate server. For a single-developer project publishing rare packages, npm's free private package tier (1 package) or GitHub Packages may be simpler.
PrismaTechWork provides end-to-end infrastructure services — from initial deployment and security hardening to ongoing monitoring, automated backups, and dedicated support. Whether you need a single-server setup or a multi-site network, our team ensures your infrastructure is built right, secured properly, and maintained reliably.
Verdaccio is a single-purpose lightweight npm-only registry — easy to set up, low resource usage, YAML configuration. Nexus Repository is a universal artifact manager supporting npm, Maven, Docker, PyPI, NuGet, and more in one server — powerful but requires 4 GB RAM and significant configuration. Choose Verdaccio if you only need private npm packages. Choose Nexus if you need a unified artifact store across multiple package ecosystems.
Yes. Verdaccio is fully compatible with yarn (v1 and v2/Berry) and pnpm. Set the registry in .yarnrc.yml for yarn Berry: npmRegistryServer: 'https://npm.yourdomain.com'. For pnpm, set registry=https://npm.yourdomain.com in .npmrc. All package manager clients that follow the npm registry protocol work with Verdaccio out of the box.
First, log in: npm login --registry https://npm.yourdomain.com. Then add publishConfig to your package.json: {"publishConfig": {"registry": "https://npm.yourdomain.com"}}. Run npm publish — the package is uploaded to Verdaccio. Other team members install it with npm install @yourscope/package-name after setting the registry in their .npmrc. The public npmjs.org never receives your private package.
Yes. After the initial internet connection where packages are fetched and cached from npmjs.org, Verdaccio serves them from its local storage. For a fully air-gapped environment, pre-warm the cache by running npm install for all dependencies once with internet, then disconnect. Subsequent installs fetch from Verdaccio's cache. Set offline: true in the uplinks config to prevent cache-miss attempts to the internet.
Create an npm token: npm token create --registry https://npm.yourdomain.com. Store it as a GitHub Actions secret (NPM_TOKEN). In your workflow, add: echo '//npm.yourdomain.com/:_authToken=${{ secrets.NPM_TOKEN }}' > ~/.npmrc before the npm install step. For publishing, add npm publish --registry https://npm.yourdomain.com with the token. Use environment-specific tokens so you can revoke CI access without affecting developers.
Scoped packages use a @scope/ prefix (e.g. @mycompany/utils). In .npmrc, map the scope to Verdaccio: @mycompany:registry=https://npm.yourdomain.com. This means @mycompany/* packages are fetched from your private registry while all other packages still go through npmjs.org. This is the recommended setup — it keeps public and private packages cleanly separated without routing all traffic through Verdaccio.
Yes. Verdaccio has a plugin system for custom storage backends. Install verdaccio-aws-s3-storage for Amazon S3 or Backblaze B2, or verdaccio-google-cloud for GCS. Configure the plugin in config.yaml under the store section. This is useful for high-availability setups where multiple Verdaccio instances share the same package storage, or for offloading storage to a managed object store.
Verdaccio resolves packages in this order: local storage first, then upstream proxy. If you host @yourscope/lodash privately, that version is served — the public npmjs.org version is never fetched. For packages without a scope, be careful: a private package named lodash would shadow the public one for all users of your registry. Always use scoped names (@yourscope/package) for private packages to avoid shadowing public packages accidentally.