Journal indexDockup / field note
Note / self-host-verdaccio

How to Self-Host Verdaccio in 2026: npm Auth, Storage and TLS

A practical Verdaccio self-hosting guide covering Docker, ports, persistent data, TLS, security, backups and the failures that block production use. In 2026.

Self-hosting Verdaccio becomes interesting at the first redeploy, not the first docker run. If npm clients send auth to a different host or package storage is read-only, Docker can still report a perfectly healthy process. The deployment below is organized around observable behavior: log in with npm, publish a scoped package, install it from a clean project and confirm an upstream package is cached.

The intended job of Verdaccio is explicit: private npm registry for internal packages. That description tells us what must stay public, what should remain private and what a backup has to reconstruct.

Ports, processes and private services

A useful Verdaccio diagram shows the public route, private port 4873, state boundary and every supporting requirement. Mark which arrows carry credentials and which are ordinary user traffic. The network contract for Verdaccio is persistent configuration, htpasswd storage and optional object storage. Keep private endpoints on internal DNS, permit only required outbound calls and give Verdaccio a scoped service credential.

Prove the diagram with one real action: log in with npm, publish a scoped package, install it from a clean project and confirm an upstream package is cached. The likely pressure comes from tarball storage, metadata operations, concurrent installs and latency to configured upstream registries; monitor that path rather than treating all HTTP requests as equal.

Turn the local command into an inspectable service

Use a command that exposes every important choice. This baseline binds Verdaccio to host loopback, adds the known data mounts and supplies the first required setting. Add the reviewed connection settings for persistent configuration, htpasswd storage and optional object storage; use private names for private services.

docker run -d \
  --name verdaccio \
  --restart unless-stopped \
  -p 127.0.0.1:4873:4873 \
  -v verdaccio-data:/verdaccio/storage \
  -e VERDACCIO_PUBLIC_URL=https://app.example.com \
  verdaccio/verdaccio:latest

Replace floating tags with a tested version or digest. After startup, inspect docker logs --tail 200 verdaccio and confirm the process listens on 4873. Then execute the Verdaccio acceptance action; a root-page response cannot prove the full scenario succeeds: log in with npm, publish a scoped package, install it from a clean project and confirm an upstream package is cached.

TLS is easy; generated URLs are not

Set the public URL and npm registry URL to the same HTTPS origin. Send the chosen hostname to container port 4873, forward the original host and HTTPS scheme, and avoid publishing a second direct origin.

Test Verdaccio from a clean external client. Separate ingress failure from the known application boundary — npm clients send auth to a different host or package storage is read-only. A certificate, DNS or 502 error belongs to routing; a request that reaches Verdaccio and fails later belongs to application state, capacity or its supporting requirement. The custom-domain TLS guide covers the first group.

Restore Verdaccio on an empty host

For Verdaccio, redeploy safety starts with package tarballs, metadata, config and authentication files. Mount /verdaccio/storage before bootstrap, write harmless sample data and replace the container to prove that path is actually persistent. Test the path by replacing the container while harmless sample data exists; this exposes mounts pointed one directory too high or low.

Next test disaster recovery on a blank host. Use an application-consistent database export where necessary and verify that private tarballs, metadata, users and config return and the clean project installs the same package integrity. The restore-tested database backup guide provides a stronger target than merely checking that an archive file was created.

Credentials, roles and exposed surfaces

For Verdaccio, the valuable surface is not necessarily the landing page. The main mistake is allowing anonymous publish or using a writable uplink configuration. Counter it deliberately: deny anonymous publish, scope maintainers and keep npm authentication attached to the exact HTTPS registry host.

VERDACCIO_PUBLIC_URL is configuration rather than a secret; keep its value explicit while protecting the separate credentials used by Verdaccio. Use an unprivileged container user when the image supports it and mount no unrelated credentials. Apply rate or size limits at ingress where untrusted work can consume tarball storage, metadata operations, concurrent installs and latency to configured upstream registries.

Failure drills for Verdaccio

Capacity tests should exercise tarball storage, metadata operations, concurrent installs and latency to configured upstream registries, not a repeated request to /. Run the scenario “log in with npm, publish a scoped package, install it from a clean project and confirm an upstream package is cached” at realistic concurrency and record latency, error rate and storage growth.

Upgrade planning must account for this risk: config syntax, authentication plugins and package metadata should be tested against the target Verdaccio major version. Test the new release with representative input, then repeat the acceptance transaction and compare its result. If npm clients send auth to a different host or package storage is read-only, capture the failing transaction and inspect the first boundary involved instead of assuming ingress is responsible.

Prove the Verdaccio deployment end to end

Do not make first-user traffic the acceptance test for Verdaccio. Prepare harmless sample state and run the complete action “log in with npm, publish a scoped package, install it from a clean project and confirm an upstream package is cached”. Note the exact public URL, result, image reference and log interval associated with the run.

Replace the container and repeat without rebuilding data. Next, recover onto an empty host; the recovery condition is that private tarballs, metadata, users and config return and the clean project installs the same package integrity. Observe tarball storage, metadata operations, concurrent installs and latency to configured upstream registries in every pass and define an alert around degradation of the transaction rather than around idle container metrics.

One final check should fail on purpose: temporarily deny the test identity access to persistent configuration, htpasswd storage and optional object storage. Verify that the resulting Verdaccio message identifies the relevant boundary instead of triggering data deletion or an endless restart. Restore the valid condition and confirm the same sample transaction succeeds. Keep this short drill in the release checklist.

Keep Verdaccio explicit while Dockup handles routing

For Verdaccio, Dockup can create the route and TLS certificate, preserve mounts, deliver secrets and place persistent configuration, htpasswd storage and optional object storage on private networking while deploying to either Dockup or attached servers.

The release gate is still the concrete Verdaccio transaction: log in with npm, publish a scoped package, install it from a clean project and confirm an upstream package is cached. Also verify the restore condition — private tarballs, metadata, users and config return and the clean project installs the same package integrity. Those two checks show whether the deployment works and whether it can be recovered.

Frequently asked questions

What does Verdaccio need for a production deployment?

Route the Verdaccio container on port 4873 through one HTTPS origin. The supporting network requirement is persistent configuration, htpasswd storage and optional object storage. Do not call Verdaccio ready until you can log in with npm, publish a scoped package, install it from a clean project and confirm an upstream package is cached.

Which Verdaccio data belongs in a backup?

Persist /verdaccio/storage and include package tarballs, metadata, config and authentication files in the same recovery manifest. A clean Verdaccio restore passes only when private tarballs, metadata, users and config return and the clean project installs the same package integrity.

Does Verdaccio require HTTPS behind a reverse proxy?

Use HTTPS for the public Verdaccio origin and keep port 4873 on the internal route. Apply the Verdaccio setting correctly: set the public URL and npm registry URL to the same HTTPS origin. For Verdaccio, HTTPS protects credentials or user content in transit and keeps origin-sensitive client behavior consistent.

How should a Verdaccio upgrade be tested?

Restore current Verdaccio state into an isolated deployment, apply the candidate version and repeat its acceptance transaction. Pay particular attention because config syntax, authentication plugins and package metadata should be tested against the target Verdaccio major version. Keep the previous Verdaccio image until its data-migration and rollback boundary are understood.