Having private NPM package management can be critical to a new project of scale. Localized caching is also just really convenient. Unfortunately private resources can get expensive for small groups or startups. Even npmjs.org's $7 per user per month can be a bit heavy if it's more than a one to two developer project and I bet you already have at least 10 other monthly subscriptions costing you $9.99 each!

I landed on the well documented verdaccio/verdaccio image. I wanted a free, self hosted and maintained package and quite frankly almost everything else fell pretty short. I really wanted to avoid having to maintain yet another Docker build for a 3rd party tool.

My setup is predicated on it only being accessed over VPN and that security/privacy was not really that imperative. A few extra steps and you can lock it down in a more professional manor.

What Are We Doing

I'm going to walk you through setting this up as a container on your local docker instance as a one off. You'll be able to easily translate this instructions into any container orchestration of your choice. I'm personally using Portainer you can read my quick start guide here. If you do this on a shared server you will obviously need to change things like URLs and maybe ports below.


Create a volume for storing storage data

docker volume create verdaccio_storage;

There really is no need at this point to tweak the config, but if you checkout their webpage you can find all sorts of help on customizing the config by overriding the file or by environment variables.

docker run -d --restart unless-stopped \
	--name verdaccio \
	--publish 4873:4873 \
	--mount type=volume,src=verdaccio_storage,dst=/verdaccio \


Publish A Package

Go into your package-of-awesome project and update your package.json file with the following config

  "publishConfig": {
    "registry": "http://localhost:4873/"

Now lets setup a new user. This will add an htpasswd entry to a file in /verdaccio/.htpasswd (which is in your docker volume). This will also add an entry locally to ~/.npmrc and is worth validating post run.

npm adduser --registry http://localhost:4873

You can now run npm publish from your project and you will see it show up in the Verdaccio interface http://localhost:4873.

In order to now install that package-of-awesome into another project you will need to do one of two things. You either need to set your new NPM registry as your global default ~/.npmrc or you can do it by creating or updating the .npmrc file inside the project you are working on. Either way the config line is the same. Just add this as the first line.


Verdaccio, like I believe all the other options works as a private repo and a cache. So anything not located in this registry will be fetched from the upstream option. By default this is http://npmjs.com, however you could chain multiple instances in differenct locations together if so desired.

Verdaccio does have some great docs, this was just a quicker and more complete getting started. Please checkout their documentation to take your install to the next level.