Ambiente para serviços Node.js utilizando monorepo
Data: 19/02/2021
Autores:
- Diego Gonçalves de Almeida (Assessor)
- Rubens Fidelis Miranda Junior (Assessor)
Objetivo
Criar ambiente padrão para projetos monorepo usando Node.js com JavaScript e TypeScript.
Justificativa
Introdução
Após problemas com imagens pré-definidas de ambientes Node.js, houve a necessidade de estabelecer um padrão para manter serviços Node.js com repositórios monorepo.monorepo buscando melhorias nos processos de:
Resultados esperados
- Ambiente estável capaz de rodar todos os serviços Node.js;
- Build do serviço somente com seus arquivos e dependências;
- Consulta de logs e monitoramento de atividade do serviço.
Envolvidos
Desenvolvimento
Diego Gonçalves de Almeida (Assessor);Rubens Fidelis Miranda Junior (Assessor)
Glossário
Monorepo - é uma estratégia de desenvolvimento de software onde diversos projetos são agrupados em um grande projeto.
Node.js - é um ambiente de execução JavaScript open-source que funciona utilizando o mecanismo Chrome V8.
JavaScript - é uma linguagem de programação de alto nível que segue as especificações ECMAScript.
TypeScript - é um superconjunto sintático estrito de Javascript, criado e mantido pela Microsoft.
Build - é o processo de converter o código fonte de softwares em artefatos que podem ser executados.
VM - é uma máquina virtual, um servidor.
NPM - Node Package Manager.
LTS - Long Term Service (Suporte de longo prazo).
Git - é um software que rastreia mudanças em qualquer conjunto de arquivos.
Pipeline - é uma série de etapas que devem ser realizadas para a disponibilização de uma nova versão de software.
HTTP - Hypertext Transfer Protocol, é um protocolo de comunicação que usa a porta 80 como padrão.
HTTPS - Hypertext Transfer Protocol Secure, é um protocolo de comunicação seguro que usa a porta 443 como padrão.
Firewall - é um sistema de segurança de rede que monitora e controla o tráfego de rede com base em regras de segurança.
Package.json - é um arquivo de configuração presente na raiz de projetos Node.js. Ele armazena metadados referentes ao projeto, além de ser usado para especificar dependências e scripts do projeto.
Repositório - um local para armazenamento de informações, no caso o código fonte de softwares.
Polyrepo - é uma estratégia de desenvolvimento de software onde cada pacote de um projeto tem seu próprio repositório.
Premissas
O servidor precisa iniciar o serviço com todas as suas configurações automaticamente após uma reinicialização.
Servidor
Para o caso concreto recomendamos uma VM com Linux utilizando uma das distribuições open source baseadas no Red Hat Enterprise Linux, no caso utilizamos o Oracle Linux Service na versão 8.3. A configuração desta máquina dependerá do serviço e sua previsão de uso, neste caso, o padrão estabelecido pela Gerência de Infraestrutura entrega no mínimo VM's com 2 núcleos de processamento, 4GB de memória RAM e 40GB de armazenamento.
A versão do sistema operacional pode gerar erros de codificação no ambiente ao definir a linguagem para PT-BR, português do Brasil, para resolver este problema executamos:
sudo localectl set-locale LANG=pt_BR.UTF-8
Agora, para garantir que todos os recursos do sistema operacional sejam atualizados, é preciso executar:
sudo dnf update
sudo dnf upgrade
Node.js
É o mecanismo que vai rodar a aplicação. Para sua instalação deve ser executado:
sudo dnf module install nodejs:14
Recomenda-se a versão LTS mais recente.
Yarn
É o gerenciador de pacotes NPM utilizado para gerenciar os pacotes da aplicação. Para sua instalação deve ser executado:
sudo npm install -g yarn
TypeScript
É o pacote capaz de compilar todo o código da aplicação para JavaScript a fim de que a aplicação seja executada no Node.js. Para sua instalação deve ser executado:
sudo npm install -g typescript
PM2
É o gerenciador de processos Node.js recomendado para manter a aplicação rodando. Para sua instalação deve ser executado:
sudo npm install -g pm2
Git
Enquanto não há uma pipeline integrada nesta aplicação, recomendamos o git para manter o código da aplicação atualizado no servidor. Para sua instalação deve ser executado:
sudo dnf install git
Liberando tráfego
Para disponibilizar o serviço, é necessário que o servidor aceite requisições nas portas 80 e 443 com os protocolos HTTP e HTTPS. Para isso deve ser executado:
sudo firewall-cmd --zone=public --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --zone=public --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-service=https
Depois de adicionar as liberações é necessário recarregar o firewall. Para isso deve ser executado:
sudo firewall-cmd --reload
Nginx
É o servidor web recomendado devido a sua funcionalidade de proxy reverso para disponibilizar a aplicação para uso externo. Para sua instalação deve ser executado:
sudo dnf install nginx-all-modules
Precisamos que o nginx seja inicializado com o sistema em toda reinicialização. Para isso deve ser executado:
sudo systemctl enable nginx
Precisamos do nginx rodando para concluir sua configuração. Para isso deve ser executado:
sudo systemctl start nginx
Precisamos configurar o nginx para que responda requisições HTTP e HTTPS com a aplicação. Para isso é necessário acessar o arquivo de configuração executando:
sudo vim /etc/nginx/nginx.conf
Recomendamos que a configuração de proxy reverso da aplicação seja:
#HTTP
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name dominio.ro.gov.br;
location / {
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass http://localhost:3333;
proxy_pass_request_headers on;
}
underscores_in_headers on;
}
#HTTPS
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name dominio.ro.gov.br;
location / {
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_pass http://localhost:3333;
proxy_pass_request_headers on;
}
underscores_in_headers on;
}
Para concluir a configuração do nginx precisamos validar se a sintaxe do arquivo de configuração está correta. Para isso deve ser executado:
sudo nginx -t
Para reiniciar o nginx e colocar todas as configurações em vigor deve ser executado:
sudo systemctl restart nginx
Aplicação
Para adicionar o repositório da aplicação, precisamos criar uma pasta e clonar o repositório da aplicação. Para isso deve ser executado:
mkdir ~/app
cd ~/app
git clone https://gitlab.setic.ro.gov.br/respositorio.git
Com o repositório clonado, é necessário instalar suas dependências. Para isso deve ser executado:
cd ~/app/repositorio
yarn
Com as dependências do projeto instaladas, é necessário gerar sua build. Para isso deve ser executado:
cd ~/app/repositorio/pacote
yarn build
Com a build da aplicação concluída, o projeto pode ser inicializado. Mas antes é importante definir o script de inicialização da aplicação no arquivo package.json utilizando o pm2. Segue um exemplo:
"scripts": {
"start": "pm2 start dist/server.js --name nome-aplicacao"
}
Para inicializar o projeto, deve ser executado:
yarn start
Para adicionar os serviços do pm2 na inicialização do sistema, deve ser executado:
pm2 startup systemd
Este comando vai exibir em tela um outro comando com base nas configurações e versão do seu sistema. Para conclusão da configuração copie e execute o comando exibido em tela.
Resultado
Conclusão
Com a execução de todos os comandos citados, terá um servidor capaz de manter uma aplicação Node.js usando JavaScript ou TypeScript com repositório de código monorepo ou polyrepo cumprindo todos os requisitos levantados.