Configurando um registro NPM interno/privado com Verdaccio
--
O Verdaccio é uma alternativa simples, flexível e open-source de Registro NPM local. Em determinados contextos boa parte das empresas e organizações acabam optando por ter seus próprios servidores de registro, seja por questões ligadas a privacidade/segurança ou simplesmente por um motivo estratégico.
❗️Pré-requisitos
Para o pleno aproveitamento desta material é necessário que você tenha familiaridade com as seguintes tecnologias e ferramentas:
- Docker
- NPM, Yarn ou PNPM (ao longo deste material utilizarei NPM, porém, os outros gerenciadores também são totalmente compatíveis)
👨💻 Preparando o ambiente
O processo de configuração e subida do ambiente é muito simples e rápido!
Configuração
Vamos criar e acessar nosso diretório de trabalho:
mkdir verdaccio && cd verdaccio
Agora crie um diretório chamado conf
e dentro do mesmo um arquivo config.yaml
com o seguinte conteúdo:
storage: /verdaccio/storage
plugins: /verdaccio/plugins
web:
title: Verdaccio
auth:
htpasswd:
file: /verdaccio/storage/htpasswd
#max_users: -1
uplinks:
npmjs:
url: https://registry.npmjs.org/
packages:
'@*/*':
access: $all
publish: $authenticated
unpublish: $authenticated
proxy: npmjs
'my-company-*':
access: $all
publish: $authenticated
unpublish: root
'**':
access: $all
proxy: npmjs
middlewares:
audit:
enabled: true
logs: { type: stdout, format: pretty, level: http }
Vamos entender algumas das configurações mais relevantes:
auth.htpasswd
:- =>
file
: este arquivo armazena os metadados referente aos usuário cadastrados; - =>
max_users
: define o número máximo de usuários que podem se registrar. Quando definido como-1
desabilita o registro de novos usuários. uplinks
: cria alias para outros servidores de registro. No exemplo acima criamos um alias para o repositório padrão do NPMJS (entenderemos seu uso mais adiante);packages
:- =>
@*/*
: qualquer pacote que case com essa regex é considerado de escopo de usuário; - =>
my-company-*
: qualquer pacote que case com essa regex é considerado de domínio da organização/empresa; - =>
**
: todo e qualquer pacote que não seja capturado pelos escopos apresentados acima.
🔗 As propriedades de nível de acesso access, publish e unpublish são melhor explicadas aqui: https://verdaccio.org/docs/packages.
A propriedade proxy
indica que caso o pacote não esteja presente no servidor do Verdaccio este deve ser buscado no registro informado em uplinks.npmjs
, que no exemplo acima aponta para: https://registry.npmjs.org/
.
Já em relação a packages.my-company-*
, observe que somente o grupo root
(o nome do usuário é também o nome do seu grupo) tem autorização para despublicar (unpublish) pacotes. Observe ainda que devido a ausência da propriedade proxy, caso o pacote buscado case com a regex my-company-*
e ele não exista dentro do servidor, o mesmo não será buscado em outro local pois a propriedade proxy não dentro do seu escopo, ou seja, se o nome escolhido para este escopo for muito simples, você pode ter problemas, deste modo é valido considerar incluir a propriedade proxy para este escopo também.
Por fim packages.**
tem somente permissão de acesso, ou seja, nossos usuários só poderão publicar pacotes que casem com os dois primeiros padrões, já que **
recebeu permissão de somente acesso.
💡Caso não tenha ficado claro, o padrão
my-company-*
pode ser adotado para representar pacotes da organização ou até mesmo pacotes criados para um cliente específico.
Subindo o Verdaccio via Docker
Execute a seguinte instrução na raiz do seu diretório de trabalho:
docker run \
--rm \
--name verdaccio \
--detach \
--publish 4873:4873 \
--volume $(pwd)/conf:/verdaccio/conf \
--volume $(pwd)/storage:/verdaccio/storage \
--volume $(pwd)/plugins:/verdaccio/plugins \
verdaccio/verdaccio
Acesse o seguinte endereço no seu navegador: http://localhost:4873.
Essa será a tela apresentada:
Operações básicas
Toda vez que precisar logar, deslogar, baixar, publicar ou despublicar um pacote você terá que informar o parâmetro --registry http://localhost:4873
, com o tempo isso se torna um pouco repetitivo demais, porém, existem duas formas de contornar este "problema".
Solução 1 - Execute:
npm set registry http://localhost:4873/
Isso irá adicionar o seguinte valor registry=http://localhost:4873/
ao arquivo ~/.npmrc
, ou seja, este registro será globalmente reconhecido pelo NPM.
Solução 2 - Crie um arquivo .npmrc
na raiz do seu repositório de código e adicione o valor registry=http://localhost:4873
a ele, você pode até versionar este junto com o projeto, afinal de contas ele possui escopo local e afeta somente o projeto de mesmo nível e níveis inferiores!
Para cadastrar um usuário basta executar:
npm adduser --registry http://localhost:4873/
Lembre-se que caso esteja utilizando o
.npmrc
local ou global conforme apresentado anteriormente, você poderá omitir o parâmetro--registry http...
.
Ao executar a instrução acima você deverá preencher algumas informações que serão solicitadas pela CLI. Sendo elas: Username
, Password
e Email
. Caso tudo corra bem a CLI irá apresentar a mensagem Logged in as fabio on http://localhost:4873/.
, ou seja, você está logado com o usuário que acabou de ser criado, neste exemplo criei o usuário fabio
.
Caso você precise deslogar:
npm logout --registry http://localhost:4873/
Já se precisar logar novamente:
npm login --registry http://localhost:4873/
Para alterar a senha do usuário atualmente logado:
npm profile set password --registry http://localhost:4873/
Publicando um pacote
Para exemplificar o processo de publicação de um pacote, nada mais justo do que criarmos e publicarmos um pacote em nosso Registro NPM. Sendo assim crie um diretório chamado hello-world
, acesse este e inicialize o mesmo como um repositório NPM:
npm init -y
Edite o arquivo package.json
e altere o valor hello-world
para:
@fabio/hello-world
@fabio representa o escopo do usuário que eu criei no servidor, ou seja, estou falando que o pacote em questão é de propriedade deste usuário. Caso tenha criado um usuário com outro nome, faça os devidos ajustes.
Crie um arquivo README.md
com o seguinte conteúdo:
# @fabio/hello-worldIsso é um README.md de exemplo.
Crie um arquivo index.js
e adicione este conteúdo a ele:
module.exports = function () {
console.log('Hello, world!');
}
⚠️ Para executar os passos abaixo é necessário que você tenha criado um usuário e esteja logado, estes passos já foram ensinados em tópicos anteriores.
Execute essa instrução para publicar o pacote:
npm publish --registry http://localhost:4873/
Acesse o servidor em: http://localhost:4873 e visualize o seguinte resultado:
Ao clicar sobre o pacote temos está tela de resultado:
Baixando/instalado o pacote
Agora você poderia facilmente baixar e instalar o pacote executando essa instrução:
npm install --registry http://localhost:4873/ @fabio/hello-world
Posteriormente poderia simplesmente importar em seu código/projeto e sair usando. Ex:
const hello = require('@fabio/hello-world')hello()
Despublicar um pacote ou versão do Registro NPM
Para despublicar/remover uma versão especifica basta informar a mesma logo após o nome do pacote:
npm unpublish --registry http://localhost:4873/ @fabio/hello-world@1.0.0
Já para despublicar o pacote como um todo, basta executar:
npm unpublish --registry http://localhost:4873/ @fabio/hello-world -f
✌️Conclusão
O Verdaccio é um projeto que não apresenta de forma nativa recursos avançados de gestão de acesso, porém, por ser uma solução open-source e construída utilizando basicamente TypeScript, você tem uma liberdade muito grande para adicionar controles customizados ou até mesmo criar plugins para atender quaisquer outras necessidades que venham a surgir.
Recomendo ainda que acesse a documentação oficial em https://verdaccio.org/docs e veja o que a ferramenta tem a oferecer.