Preparando um ambiente Linux para aplicações com NodeJS, MySQL e ReactJS.
Tags: linux, node, mysql, braziliandevs
Published: 2020-11-05 13:20:11

Recentemente tive a necessidade de subir uma aplicação com o seguinte stack: NodeJS e Mysql no backend e ReactJS no frontend. Como não tinha conhecimento prévio dessas tecnologias, foi um grande desafio desenvolver a aplicação e ainda mais desafiador montar um ambiente para receber tudo isso. Depois de diversas tentativas, fiz um mini-tutorial para facilitar a vida de quem precisa de um ambiente Linux com essas características.

> Uma dica antes de iniciar, é verificar se o fuso horário do ambiente está como desejado, é possível utilizar o seguinte comando para resolver isso:
```
$ sudo dpkg-reconfigure tzdata
```
---

#1 - Instalando o MySQL:

Primeiramente, vamos realizar a instalação e configuração do MySQL, que vai ser nosso SGBD.
```
$ sudo apt update
$ sudo apt install mysql-server
```
Após executar esses dois comandos, inicia a configuração inicial do MySQL:
```
$ sudo mysql_secure_installation
```

---

#2 - Configuração do MySQL:

Após a instalação, vamos configurar o MySQL, acessando o mesmo através do seguinte comando:
```
$ sudo mysql -u root -p
```
Obs.: no primeiro acesso, não é necessário digitar nenhuma senha
Definimos a senha para o usuário:
```
mysql> ALTER USER root@'localhost' IDENTIFIED WITH mysql_native_password BY 'SUA_SENHA';
```
Importante: o uso do mysql_native_password é necessário para evitar que drivers de conexão mais antigos tenham incompatibilidade na hora de realizar acesso a base de dados
Criamos um usuário para acesso:
```
mysql> CREATE USER 'SEU_USUARIO'@'localhost' IDENTIFIED WITH mysql_native_password BY 'SUA_SENHA';
```
Definimos os privilégios de acesso para o usuário criado:
```
mysql> GRANT ALL PRIVILEGES ON *.* TO 'database_user'@'localhost';
```
Podemos definir uma base específica para o usuário, nesse caso ele terá acesso a todas as bases no MySQL.
```
mysql> FLUSH PRIVILEGES;
mysql> EXIT;

Atualiza os privilégios de acesso dos usuários e saímos do console do MySQL.
```
Para não ocorrer erros em algumas consultas em formato "antigo", é necessário configurar o modo SQL que o MySQL trabalha, alterando o arquivo mysqld.cnf:
```
$ sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
```
Adicionamos no final do arquivo a linha:
```
sql_mode="TRADITIONAL"
```
Após todas as alterações, é necessário reiniciar o serviço do MySQL:
```
$ sudo service mysql restart
```
Acessamos novamente o MySQL e criamos a base de dados desejada:
```
$ mysql -u root -p
mysql> CREATE DATABASE NOME_DESEJADO
mysql> EXIT;
```
Caso necessário, podemos restaurar uma base já existente:
```
$ mysql -u usuario -p 'nomebase' < NOMEBACKUP.sql
```
Pronto, temos o MySQL instalado e configurado, agora vamos para a configuração do nosso proxy reverso, o Nginx.

---

#3 - Instalando o Nginx:

NGINX, pronunciado "engine-ex", é um dos servidores web mais populares no mundo e é responsável por hospedar alguns dos maiores e mais acessados sites na internet. Pode ser utilizado como servidor web ou proxy reverso.
```
$ sudo apt update
$ sudo apt install nginx
```

---

#4 - Ajustando o firewall

O Nginx se registra como um serviço com o ufw após a instalação, tornando bem fácil permitir o acesso ao Nginx.
Podemos listar as configurações das aplicações com as quais o ufw sabe como trabalhar digitando:
```
$ sudo ufw app list
```

Você deve obter uma listagem dos perfis de aplicativo:
```
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH
```
Agora vamos permitir algumas aplicações:
```
$ sudo ufw allow 'Nginx HTTP' //Permite o Nginx
$ sudo ufw allow 'OpenSSH' //Permite o OpenSSH
```
Caso deseje adicionar mais de uma aplicação na mesma máquina, utilize o comando:
```
$ sudo ufw allow [porta/protocolo]
$ sudo ufw enable //Ativa o firewall
$ sudo ufw status //Verifica o status
```
Para verificar se o Nginx está rodando, basta digitar:
```
$ systemctl status nginx
```

---

#5 - Instalar o NodeJS
Para facilitar o gerenciamento de pacotes, vamos utilizar o Yarn, que é um gerenciador de pacotes Javascript da empresa Facebook

Instalando o NodeJS
```
$ sudo apt install nodejs
```
Instalando o gerenciador de pacotes, NPM
```
$ sudo apt install npm
```
Instalando o Yarn:
```
$ sudo npm install yarn -g
```
Caso ocorram problemas ao instalar o Yarn dessa forma, a possível solução é:

```
sudo apt remove cmdtest
sudo apt remove yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update
sudo apt-get install yarn
```

Antes de realizar a cópia dos arquivos para o servidor, recomendo realizar a build da aplicação frontend, diminuindo o trabalho do servidor para instalar e compilar todos os arquivos necessários:
Na sua pasta do frontend, rode o comando:
```
$ yarn run build
```
Para realizar a cópia dos arquivos, recomendo uma visita no link:
https://viniciussousa88.wordpress.com/2012/07/31/enviar-e-receber-arquivos-via-ssh/

Após copiar os arquivos do backend e do frontend para o servidor, acessamos a pasta do backend e realizamos a instalação das dependências:
```
$ yarn install
```
Os arquivos do frontend para a pasta var/www/NOME_APP:
```
$ cd pasta_app
$ sudo cp -r * /var/www/NOME_APP
```

---

#6 - Configurar o Nginx

Para configurar o Nginx, vamos começar alterando o arquivo default, que fica na pasta /etc/nginx/sites-available:
```
$ sudo nano /etc/nginx/sites-available/default
```
Essa é uma configuração bem enxuta, caso necessário, você pode complementar da maneira que lhe atender:
```
server {
  listen 80 default_server;
  listen [::]:80 default_server;
	
  root /var/www/NOME_APP;
  server_name _; 
	
  #Aponta para a pasta onde fica o frontend
  location / {
    root /var/www/NOME_APP/;
    try_files $uri /index.html;
  }
  #Localização da aplicação backend, nesse caso nomeamos como api
  #A PORTA é a que está configurada na aplicação backend
  location /api/ {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-NginX-Proxy true;
    proxy_pass http://localhost:PORTA/;
    proxy_ssl_session_reuse off;
    proxy_set_header Host $http_host;
    proxy_cache_bypass $http_upgrade;
    proxy_redirect off;
  }
}
```
Após configurar e salvar o arquivo, verificamos se está tudo certo e reiniciamos o serviço:
```
$ sudo nginx -t
$ sudo systemctl reload nginx
```

---

#7 - PM2

O PM2 é um gerenciador de processos e com ele lidar com variáveis ambientes, fazer log, saber o estado da aplicação se tornam tarefas simples. Vamos utilizar ele para manter a aplicação rodando ao invés de utilizar apenas o node.
Instalando o PM2:
```
$ sudo npm install pm2@latest -g
```
Após instalar o PM2, acessamos a pasta onde está nossa aplicação backend e rodamos o comando:
```
$ pm2 start index.js --name MEUAPP
```
O comando acima, executa o index.js que ficará rodando em background e nomeia o processo aberto para MEUAPP, caso deseje também é possível manipular o processo através do ID, que inicia em zero.

Podemos também configurar o PM2 para iniciar juntamente com o sistema, em caso de reinicializações:
```
$ pm2 startup systemd
```
Para salvar a lista de processos:
```
$ pm2 save
```
O PM2 facilita muito o gerenciamento das aplicações, eis alguns comandos úteis para o mesmo:
```
$ pm2 list  //Lista de aplicações rodando
$ pm2 info app_nome //Infos do app
$ pm2 stop app_name_or_id //Para o app
$ pm2 restart app_name_or_id //Restarta o app
Caso deseje visualizar os logs da aplicação, eles ficam na pasta:
/home/usuario/.pm2/logs
```

---

Após realizar essas configurações, seu ambiente vai estar pronto para rodar sua aplicação.


---

Considerações finais:

Fiz esse tutorial pois encontrei muitos materiais disponíveis, porém senti falta de algum exemplo que fizesse todo o processo. Após ter feito essa configuração uma primeira vez e anotado todos os comandos, ficou bem mais rápido e prático criar uma ambiente para aplicações com NodeJS e MySQL. Espero que gostem, críticas e sugestões são muito bem-vindas.


---

Links úteis:

Criando uma máquina virtual na Azure (utilizei para realizar os primeiros testes): https://docs.microsoft.com/pt-br/azure/virtual-machines/linux/quick-create-portal
 
Copiando arquivos via SSH: https://viniciussousa88.wordpress.com/2012/07/31/enviar-e-receber-arquivos-via-ssh/
 
Alterando o fuso horário no Linux: https://www.vivaolinux.com.br/dica/Alterando-o-fuso-horario-no-Linux
 
Configurando um servidor Ubuntu, instalando o Nginx e configurando aplicações NodeJS: 

https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04

https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04