Artigo original: How to Deploy a Node.js App – From Server Setup to Production

Neste tutorial, vamos aprender tudo que é preciso para fazer o deploy de uma aplicação em Node para um servidor de produção.

Para começar, vamos alugar um servidor na Digital Ocean. Depois disso, vamos configurar o servidor, fazer a conexão, instalar o Nginx e configurá-lo, extrair ou criar nossa aplicação do Node.js e executá-la como um processo.

Como você pode ver, há muito para ser feito e teremos várias opções. Então, vamos começar.

Você deve ter algum conhecimento básico de como o Terminal funciona e já ter trabalhado com Vi/Vim antes de iniciar o tutorial. Se você não estiver familiarizado com os comandos básicos, eu recomendo ler sobre eles.

Eu vou executar os comandos em um MacOS. Se você quiser seguir esse tutorial em um Windows,  pode usar o Powershell ou algum tipo de emulador para Unix.

Embora eu esteja usando o Node.js como uma plataforma para o nosso exemplo de aplicação, muitas etapas são iguais para qualquer tipo de aplicação para a web.

Por que a Digital Ocean?

Eu escolhi a Digital Ocean pois é barata e a interface é muito fácil de usar, comparada a outras, como a da AWS. Além disso, junto com o pacote para estudantes do GitHub, você recebe US$ 100 de crédito. Desse modo, você não terá que pagar por nada durante alguns meses. É o ideal para um projeto ou um curso.

Ela posssui um conceito chamado Droplets, que é basicamente a sua parte do servidor. Você pode pensar no servidor como um apartamento em que você pode alugar um quarto.

Droplets funcionam com a ajuda de máquinas virtuais que rodam dentro do servidor. Portanto um Droplet é a sua máquina virtual dentro do servidor dividido. Por ser uma máquina virtual, sua CPU e memória são compartilhados e podem ser facilmente aumentados. Isso pode ser feito através de um investimento em dinheiro junto ao provedor.

Como criar um projeto na Digital Ocean

image-3

Assumindo que você já se inscreveu e está logado na Digital Ocean, o primeiro passo é criar o projeto que conterá nosso Droplets.  Clique no botão "New Project" no menu do lado esquerdo. Ele vai pedir que você dê um nome para o seu projeto.

Screen-Shot-2021-02-22-at-13.35.06

Coloque o nome que você quiser. Ele também vai perguntar se você quer mover algum recurso, mas por enquanto apenas clique em Skip (Ignorar). Mais tarde, nós vamos criar o droplet.

Como criar um droplet no Digital Ocean

Vamos criar nosso droplet clicando no botão "Get Started" (Iniciar).

image-4-1024x593

Após clicar no botão, ele vai pedir para escolhermos uma imagem para a máquina virtual.

Screen-Shot-2021-02-22-at-13.12.43-1024x567
Como selecionar uma imagem

Nesta parte, eu selecionei Ubuntu 20.04 pois é a versão mais atual e "LTS" no momento em que estava escrevendo. LTS significa "Long Term Support" (suporte de longo prazo), sendo a versão segura mais atual. É melhor usar a versão LTS para os projetos, porque isso garante que o provedor dará suporte e poderá ser mantida por muito tempo. Assim, você não terá problemas a longo prazo.

Eu escolhi o Ubuntu e recomendo a sua utilização, já que é o sistema Linux mais comum. Isso significa que também é o mais fácil para encontrar soluções para suas perguntas no futuro.

Você pode optar por ter uma CPU dedicada, se precisar. Se estiver criando uma startup ou qualquer tipo de negócio, eu recomento da leitura deste artigo (texto em inglês), que contém detalhes sobre como escolher a melhor opção para você.

Nesse caso, eu selecionei a opção mais barata.

Em seguida, você deve selecionar a região do datacenter. Você deve escolher a mais perto de você para diminuir o delay da rede.

image-2-1024x519
Como selecionar um datacenter

Em seguida, selecione "SSH Keys" como forma de autenticação, pois é a opção mais segura.

image-5-1024x459
Método de autenticação

Para se conectar ao servidor, será preciso gerar uma nova chave SSH no seu próprio dispositivo e adicioná-la a Digital Ocean.

Como gerar uma chave SSH

Eu vou gerar a chave através do meu macOS. Se você estiver usando o Windows, você pode verificar este artigo (texto em inglês). Abra o terminal e crie uma pasta SSH:

cd ~/.ssh

Para criar sua chave SSH:

ssh-keygen

Se o seu computador disser que não reconhece esse comando, você deve instalá-lo através do brew.

image-7-1024x140

Ele vai pedir que você nomeie o arquivo e acrescente uma senha. Não digite o seu nome. Apenas aperter Enter e continue com as definições padrão. Os arquivos devem ser gerados. Eu nomeei o meu como digital-ocean-ssh. Não se confunda com isso.

❯ lsid_dsa      id_rsa      known_hosts

Nossa chave pública é id_dsa e id_rsa é a nossa chave privada. Se você esquecer qual é a privada, você sempre pode fazer um print delas.

Como adicionar sua chave SSH na Digital Ocean

Agora, vamos copiar nossa chave pública e fazer o upload dela na Digital Ocean. Assim, eles saberão qual é a chave usada para nossa autenticação.

image-9-1024x149

Copie toda a chave, incluindo a parte ssh-rsa.

Clique em "New SSH Key":

image-10

Cole a chave na caixa de texto que aparece depois que você clica no botão. Desse modo, você verá sua chave SSH.

image-11

Como conectar ao servidor

Vamos usar o terminal para conectar ao nosso servidor através do SSH. Você também pode dar uma olhada no Termius para uma interface mais agradável, se você quiser.

Execute este comando no seu terminal após substituir IP_ADDRESS pelo IP do seu servidor (você pode procurar no painel da Digital Ocean).

ssh root@IP_ADDRESS

Se tudo der certo, agora, você deve estar no terminal do servidor. Estamos conectados ao servidor. Se você tiver qualquer tipo de erro, pode fazer o debug executando o comando com "-v" ou "-vv".

Como configurar o seu servidor

Precisamos fazer uma configuração inicial do servidor antes de fazer o deploy da aplicação no Node.

Atualize o software

Precisamos fazer a atualização do software do servidor para ter certeza de que está com a versão mais recente.

Muitos servidores são vulneráveis a ataques, pois estão usando versões antigas do software, com vulnerabilidades já conhecidas. Os invasores buscam por vulnerabilidades no software e tentam explorar isso para ter acesso ao seu servidor.

Você pode atualizar o seu Ubuntu usando o comando "apt update".

apt updateHit:1 https://repos.insights.digitalocean.com/apt/do-agent main InReleaseGet:2 http://mirrors.digitalocean.com/ubuntu focal InRelease [265 kB]      Hit:3 http://mirrors.digitalocean.com/ubuntu focal-updates InRelease                Get:4 http://security.ubuntu.com/ubuntu focal-security InRelease [109 kB]Hit:5 http://mirrors.digitalocean.com/ubuntu focal-backports InReleaseFetched 374 kB in 1s (662 kB/s)                          Reading package lists... DoneBuilding dependency tree       Reading state information... Done96 packages can be upgraded. Run 'apt list --upgradable' to see them.

Se a mensagem estiver dizendo "96 packages can be upgraded", significa que ainda não houve a instalação dos pacotes, apesar de eles terem sido encontrados para atualizar.

Para efetivar a atualização com a instalação dos pacotes encontrados, execute o comando:

apt upgrade

Digite "y" quando solicitado e isso fará a atualização do software.

Criando um usuário

Estamos conectados ao servidor como um usuário root (usuário com mais privilégios). Ser o usuário root pode ser perigoso e pode nos expor a mais vulnerabilidades.

Portanto, devemos criar um usuário para não executar os comandos como root. Substitua $username abaixo com o nome de usuário da sua preferência.

whoamiroot
adduser $username

Você vai criar uma senha para o usuário. Depois disso, ele fará várias perguntas. Para pular isso, digite "y" até que ele termine.

O novo usuário foi criado, mas ainda precisamos adicionar o novo usuário ao grupo "sudo" para que ele possa executar qualquer tipo de ação necessária.

usermod -aG sudo $USERNAME

Adicionamos o usuário ao grupo com o comando -aG (grupo a ser adicionado). Também devemos adicioná-lo ao grupo sudo.

Ainda estamos no usuário root. Então, vamos mudar para nosso novo usuário. Para isso, podemos usar o comando su (usuário a ser usado).

su $USERNAME

Após, se você executar o comando whoami, você deve ver o seu nome de usuário. Você pode verificar a existência do grupo sudo, através do seguinte comando:

sudo cat /var/log/auth.log

Apenas superusuários podem ver esse arquivo. A máquina pedirá a sua senha após executar o comando.

Copie a chave SSH

Após criar o usuário, ainda devemos habilitar seu login através do SSH.

Portanto, devemos copiar a chave pública (criada anteriomente) e colá-la na pasta SSH desse usuário para que o SSH possa saber qual chave ele deve aceitar para autenticar esse usuário.

mkdir -p ~/.ssh

O comando -p cria um diretório, caso ele não exista.

vi ~/.ssh/authorized_keys

Temos que usar o vi ou vim para criar o arquivo chamado authorized_keys.

Copie a chave pública (arquivo id_dsa) e pressione "i" para ir para o modo de edição. Cole a chave no arquivo com CMD + V.

Pressione Esc para sair do modo de edição, digite :wq para salvar e sair.

Se tiver algum problema usando Vim/Vi,  você pode dar uma olhada em algum dos vários tutoriais (texto em inglês) que explicam como eles funcionam.

Conecte ao servidor com o novo usuário

Agora, devemos ser capazes de conectar ao servidor sem nenhum problema. Você pode usar o seguinte comando para conectar (mas lembre-se de alterar o IP_ADDRESS para o seu nome de usuário).

ssh $USERNAME@IP_ADDRESS

Se você tiver algum problema, pode excluir o droplet e iniciar novamente. Isso não deve tomar muito tempo, já que fazer o debug do servidor pode ser muito difícil.

Como desabilitar o login do root

Uma boa prática de segurança é desabilitar o login através do usuário root.

Para não termos problemas de permissão no futuro, é indicado alterar a permissão do arquivo.

chmod 644 ~/.ssh/authorized_keys

Agora abra o arquivo sshd_config:

sudo vi /etc/ssh/sshd_config

Encontre a linha abaixo e modifique no para yes. Isso deve ser feito através do Vim/Vi.

PermitRootLogin no

Salve e saia do Vim/Vi.

Como instalar o Node.js e o Git

Agora, podemos seguir com a instalação do Node.js e do Git:

sudo apt install nodejs npm
sudo apt install git

Estamos prontos para criar nossa aplicação em Node e executá-la. Você pode extrair o seu projeto do Node do GitHub ou criar um projeto em Node aqui apenas para testar se funciona.

Vá para o diretório de sua escolha e crie o arquivo "app.js":

sudo vi app.js

Você pode colar o seguinte texto em seu arquivo app.js:

const express = require('express');const app = express();const port = 3000;app.get('/', (req, res) => {        res.send('Hello World');});app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Agora, execute isso com o comando:

node app.js

Você deve ser a seguinte mensagem no seu terminal: "Example app listening on port 3000!"

Podemos confirmar se está funcionando através de uma requisição:

GET http://IP_ADDRESS:3000/

Envie essa requisição de um client HTTP com o Postman ou de seu navegador. Você deve receber a seguinte mensagem: "Hello World".

Neste ponto, você deve ter percebido que alguma coisa está errada. Usuários comuns não sabem enviar uma requisição através da porta 3000.

Devemos redirecionar as requisições enviadas pelo nosso IP que chegam ao servidor para a Porta 3000. Podemos fazer isso com a ajuda do Nginx.

image-16

Como instalar e configurar o Nginx

Vamos usar o Nginx para fazer um proxy reverso para redirecionar as requisições para a nossa aplicação do Node.

image-14-1024x531
Nginx como proxy reverso

Vamos instalar o Nginx:

sudo apt install nginx

Iniciando o serviço Nginx:

sudo service nginx start

Podemos testar enviando uma requisição ao nosso servidor através do navegador. Digite o endereço de IP do servidor em seu navegador e você deverá receber a seguinte mensagem:

image-15-1024x231

É importante saber que o servidor do Nginx é executado do endereço "/var/www/html" por padrão e que você pode encontrar esse arquivo HTML nesse diretório.

Eu também aconselho a você criar uma pasta dentro de "/var/www", chamar a aplicação e mover a sua aplicação em Node para essa pasta, facilitando sua localização.

Como configurar o proxy reverso do Nginx

Vamos editar a configuração do arquivo Nginx para configurar o proxy reverso:

sudo vi /etc/nginx/sites-available/default

Nesse arquivo, você deve encontrar o local/bloco e editá-lo da seguinte maneira:

location / {                # First attempt to serve request as file, then                # as directory, then fall back to displaying a 404.                proxy_pass http://127.0.0.1:3000/;        }

O proxy_pass faz o proxy da solicitação para uma porta específica. Vamos dar à porta o endereço em que nossa aplicação de Node está executando.

Agora, vamos reiniciar o Nginx para que as alterações tenham efeito:

sudo service nginx reload

Após essa etapa, devemos ser capazes de ver a mensagem quando enviamos a requisição ao servidor.

Screen-Shot-2021-02-24-at-01.10.33-1024x67

Parabéns, nós completamos o mínimo de passos para fazer o deploy de uma aplicação em Node. Eu aconselho, no entanto, a concluir a parte de bônus, pois acredito que seja muito importante. Se você não conseguir ver a mensagem Hello World!, pode verificar se a sua aplicação e se o Nginx estão sendo executados e reiniciá-los.

Como executar sua aplicação como um processo

Não queremos ter que iniciar nossa aplicação manualmente todas as vezes que algo der errado e ele travar. Nós queremos que ela reinicie sozinha. Além disso, sempre que o servidor iniciar, a aplicação também deve iniciar.

Para fazer isso, podemos usar o PM2. Vamos instalá-lo e configurá-lo.

sudo npm i -g pm2

Estamos instalando o pm2 de modo global, usando a opção "-g". Isso faz com que ele seja acessível a todas as pastas.

pm2 start app.js

Isso garante que a aplicação será reiniciada se ocorrer algum erro.

Salve a lista de processos.

pm2 save

Também precisamos convertê-lo em um daemon que execute sempre que o sistemar iniciar:

pm2 startup systemd
image-17

Para lembrar, neste tutorial, estou usando os comandos para Ubuntu. Se você estiver usando outra distribuição do Linux, você deve substituir o comando systemd.

Podemos confirmar que está reiniciando o servidor corretamente enviando uma solicitação sem executar app.js manualmente:

sudo reboot

Depois de enviar a requisição, como fizemos anteriormente, você deve ver a mensagem "Hello World!".

Conclusão

Neste tutorial, começamos do zero, alugamos um servidor, conectamos a ele e o configuramos para a nossa aplicação do Node.js na porta 80.

Se você acompanhou e conseguiu concluir todas as etapas, parabéns! Você pode se orgulhar, pois não foi um tutorial fácil. Espero que você tenha aprendido muito. Agradeço pelo seu tempo.

Estou planejando explorar mais este tópico conectando o servidor ao domínio e, em seguida, conectando-o ao CircleCI para integração contínua. Também vou mostrar quais são as etapas necessárias para preparar sua aplicação em Node.js/React para produção. Este artigo já ficou longo. Então, esses tópicos estão reservados para outro artigo. 🙂

Se você gostou da leitura e quer se manter informado sobre futuros artigos do autor, pode se inscrever no blog pessoal dele. Se estiver interessado, lá você verá as publicações mais antigas do autor, que costuma escrever sobre desenvolvimento para a web.