Artigo original: How to deploy a React app to production on AWS using Express, Postgres, PM2 and nginx

Neste tutorial, vou guiá-lo através de uma configuração de implantação em nível de produção na AWS a partir do zero. Vou presumir que você tem pouco ou nenhum conhecimento prévio sobre AWS e que você é um iniciante.

Configuraremos uma aplicação full-stack do React Express com um banco de dados PSQL. Implantaremos a aplicação em uma instância da AWS EC2 executando uma Amazon Linux AMI 2. A configuração usará NGINX como um proxy reverso e PM2 como o gerenciador de clusters. O banco de dados PSQL será implantado na AWS RDS.

Vamos nos manter dentro do nível gratuito. Assim, seguir este tutorial não custará nada.

Por que aprender AWS?
AWS é atualmente a maior plataforma de computação em nuvem. O Wordpress alimenta mais sites pequenos, mas a AWS é usada pela grande maioria dos sites comerciais de alto tráfego. Isso significa que pessoas com habilidades em AWS estão em grande demanda.

Você pode assistir a uma versão em vídeo deste tutorial aqui.

Comandos úteis do terminal:
https://github.com/iqbal125/terminal_commands_fullstack

Teoria

  • Como funciona a rede na computação em nuvem da AWS
  • Instância da AWS EC2
  • Endereços IP públicos x privados
  • Endereços IPv4
  • Conectando-se à internet pública a partir de uma rede privada
  • Visão geral conceitual da VPC da AWS
  • Como funcionam as sub-redes na AWS
  • SSH

Prática

  • Implantação simples do EBS
  • Configuração da VPC e sub-redes
  • Gateways da internet e tabelas de roteamento
  • Configuração de grupos de segurança
  • Implantação de um computador em nuvem com AWS EC2
  • Configuração do banco de dados na AWS
  • Configuração da build do React para produção
  • Configuração do PM2
  • Configuração do Nginx

Teoria

A computação em nuvem simplificou drasticamente a implantação de uma aplicação para a web. Sites como Digital Ocean e Heroku tornam o processo ainda mais fácil ao ocultar toda a complexidade e permitir que você implante sua aplicação com alguns passos simples.

Essas ferramentas são boas, mas o que queremos é uma configuração de computação em nuvem robusta, altamente segura e altamente performática, o que significa que vamos fazer isso do zero.

A configuração da AWS envolverá principalmente a rede. É por isso que a maior parte deste tutorial focará em conceitos e configurações de rede.

Todo o resto, como o provisionamento dos bancos de dados e instâncias EC2, é fácil de fazer na AWS. A rede será o maior desafio.

Não se preocupe, no entanto, se você não tiver nenhuma experiência em rede. Vou fornecer todas as informações de que você precisa saber.

Como funciona a rede na computação em nuvem

Ela funciona basicamente da mesma maneira que a rede funciona com hardware, exceto pelo fato de que todo o hardware (roteadores, switches, gateways de internet) é virtualizado na computação em nuvem.

A rede na computação em nuvem determina essencialmente como seus recursos virtuais se comunicam entre si e com a internet em geral.

VPCs, endereços IP e sub-redes são os conceitos mais importantes para entender sobre redes na AWS.

Isso é basicamente o que criaremos.

image-1

Teremos uma sub-rede pública e uma sub-rede privada em nossa VPC. A sub-rede pública conterá nosso servidor da web e será acessível pela internet. Nossa sub-rede privada conterá nosso banco de dados, mas não será acessível pela internet.

Nosso servidor da web e nosso banco de dados poderão se comunicar entre eles através de uma tabela de rotas.

Veremos exemplos dos dois quando configurarmos nosso projeto no console da AWS.

Endereços IP públicos x privados

Um endereço IP público é a localização de onde seu computador está na internet. No entanto, o que chamamos de internet é apenas uma das muitas redes.

Da mesma maneira que você pode ter um endereço IP na internet, você também pode ter um endereço IP em outra rede que não seja a internet.

O endereço IP é simplesmente um modo de identificar um único computador em uma rede, independentemente de essa rede ser a internet ou não.

Portanto, endereços IP privados são apenas uma maneira de identificar computadores em nossa própria rede e endereços IP públicos são uma maneira de identificar computadores na rede chamada "internet".

IPv4

IPv4 é o formato em que os endereços IP são escritos.

Exemplo de endereço IPv4: 10.12.15.22

Chamado de IPv4, pois existem 4 bytes que podem representar o endereço. Cada byte contém 8 bits e, portanto, é referido como um octeto.

Como cada octeto contém 8 bits e cada bit pode ser 0 ou 1, há 2 ^ 8 = 256 combinações diferentes. Começamos em 0. Então, um octeto pode ser um número entre 0-255. Como temos 4 octetos, temos 256 ^ 4 = 4,3 bilhões de combinações diferentes e, portanto, endereços IP!

Um endereço IPv4 é resolvido para um formato legível por humanos: "https://google.com" através de um DNS.

Também existe o IPv6, mas, para manter as coisas concisas, vamos pular isso. Precisaremos apenas conhecer o IPv4 para os fins deste tutorial.

Conectando-se à rede pública a partir de uma rede privada

Isso é feito através de um gateway da internet.

Quando uma solicitação é feita por um computador em uma rede privada, uma tabela de roteamento verifica se o destino é para um computador local ou não.

Se não for, a solicitação é encaminhada para o gateway da internet, que a encaminha para fora da rede privada e para um Provedor de Serviço de Internet, que, então, a envia para o destino pretendido.

O gateway da internet também recebe solicitações da internet.

O gateway da internet tem seu próprio endereço IP público. Uma rede pode ter somente um endereço IP público, mesmo que tenha milhares de endereços IP privados.

O protocolo usado para enviar e receber dados é chamado de TCP. Este é um padrão e um modelo que assegura a integridade e confiabilidade dos dados.

VPC e sub-redes

VPC e sub-redes são, de longe, as coisas mais difíceis de entender e aprender na AWS. Por isso, dedicarei uma seção mais longa a eles.

A Nuvem Privada Virtual (em inglês, VPC ou virtual private cloud) é uma localização virtual onde você pode implantar recursos da AWS. Você pode implantar servidores da web, bancos de dados, servidores de arquivos e serviços de mensagens em uma VPC e ter todos os seus recursos contidos em um único lugar virtual.

Cada recurso tem seu próprio endereço IP privado.

Uma sub-rede (subnet) é uma parte menor da sua VPC inteira. As sub-redes são, essencialmente, uma maneira de dividir sua VPC por razões de desempenho e segurança.

Exemplo: utilizamos isso para implantar um banco de dados em uma sub-rede que seja inacessível pela internet, enquanto uma outra sub-rede possui os servidores da web que precisarão ser acessíveis pela internet. Mesmo que essas duas sub-redes sejam separadas, elas ainda fazem parte da mesma VPC.

As sub-redes na AWS são feitas com a notação CIDR.

Exemplo de notação CIDR para sub-rede: 10.11.12.0/24

Máscara de sub-rede
A máscara de sub-rede determina o número de endereços IP disponíveis para a sub-rede. O /24 é a máscara de sub-rede.

Uma máscara de sub-rede é usada como uma maneira de dividir sua sub-rede em um número aproximado de endereços IP.

Prefixo de rede: são os octetos iniciais inalteráveis que identificam uma sub-rede ou VPC única.

Endereço do host: os endereços IP disponíveis para uso nos diferentes recursos em uma sub-rede.

/24 significa que os primeiros 24 bits devem ser usados como prefixo de rede e, portanto, são inutilizáveis. Como um IPv4 tem 32 bits no total, temos 8 bits restantes, que são conhecidos como endereço do host. Esses são os endereços IP utilizáveis. Como 8 bits têm 256 combinações, nossa sub-rede pode ter qualquer endereço entre 10.11.12.0 e 10.11.12.255

Os números 1 representam o prefixo de rede e os números 0 representam o endereço do host

/24 = 255.255.255.0 = 11111111.11111111.11111111.00000000

Isso é igual a:

10.11.12.0/24

10.11.12.0/255.255.255.0

10.11.12.0/11111111.11111111.11111111.00000000

Uma sub-rede não precisa ser dividida uniformemente em octetos.

10.11.12.0 /19 significa uma máscara de sub-rede de 11111111.11111111.11100000.0000000

Se formos a um calculador de sub-rede, podemos ver como isso funciona. Um calculador de sub-rede fornece o número de endereços IP disponíveis em uma sub-rede, além de fornecer o endereço IP mínimo e máximo.

image-71

Como você pode ver, essa sub-rede nos dá um total de 8190 endereços IP utilizáveis.

Os dois primeiros octetos são todos 1s. Então, eles são usados como o prefixo de rede e podem ser qualquer número entre 0-255.

Nosso terceiro octeto, porém, tem apenas o prefixo de rede parcial e temos apenas 5 bits para usar como nosso endereço do host. Isso significa que o segundo octeto pode ser apenas um número entre 0-31, já que 2 ^ 5 = 32.

Nosso último octeto é todo 0, então, normalmente, pode ser qualquer número entre 0-255.

Tudo isso significa que nossa sub-rede pode ter qualquer endereço entre

10.11.0.0 - 10.11.31.255

Observação: os primeiros e últimos endereços IP são usados como endereços de rede e transmissão, que são endereços IP especiais com funções especiais. É por isso que o Host min é o segundo endereço IP e o Host Max é o penúltimo endereço IP.

Você pode aprender mais sobre endereços de rede e transmissão aqui (em inglês):

Para evitar toda a complexidade mencionada acima, é melhor ficar com máscaras de sub-rede de /8 /16 /24. Fazendo isso, você garantirá que não haverá octetos parciais.

10.11.12.0/8 terá os últimos 3 octetos inteiros disponíveis como endereços IP

10.11.12.0/16 terá os últimos 2 octetos inteiros disponíveis como endereços IP

10.11.12.0/24 terá o último 1 octeto inteiro disponível como endereços IP

Exemplo real
VPC: 10.11.0.0/16

Sub-rede pública 1: 10.11.1.0/24, qualquer endereço IP entre 10.11.1.0 e 10.11.1.255
Sub-rede pública 2: 10.11.2.0/24, qualquer endereço IP entre 10.11.2.0 e 10.11.2.255

Sub-rede privada 1: 10.11.3.0/24, qualquer endereço IP entre 10.11.3.0 e 10.11.3.255

Sub-rede privada 2: 10.11.4.0/24, qualquer endereço IP entre 10.11.4.0 e 10.11.4.255

Observação: nem todos os endereços IP estarão disponíveis para sua sub-rede. Alguns endereços, como os de rede e de transmissão, bem como alguns outros endereços de utilidade, serão reservados pela AWS.

AWS EC2

É o "computador" na computação em nuvem. É essencialmente um computador virtual. Tem tudo o que seu computador doméstico possui: CPU, RAM, disco rígido etc.

Existem também outros sistemas operacionais Linux disponíveis, como Ubuntu e Red Hat, assim como sistemas operacionais baseados em Windows disponíveis, tais como o Windows Server. Sistemas Windows permitem que você use uma interface gráfica de usuário (GUI) se preferir não trabalhar com a linha de comando.

Um único computador EC2 é referido como uma instância.

SSH

Secure shell: usado para fazer login no nosso servidor Linux EC2 a partir do nosso computador pessoal.

Você pode usar o Putty para SSH se preferir uma interface gráfica.

Eu usarei o Git Bash. É mais simples de usar, mas não tem uma GUI.

Vamos utilizar chaves privadas e públicas para SSH. Ambas são geradas pela AWS.

A chave privada será armazenada no seu próprio computador e será usada durante o processo de login.

A chave pública será armazenada na Amazon e permitirá os logins. A chave pública não precisa ser mantida em segredo. A chave privada deve ser mantida em um lugar seguro no seu computador. Se você a apagar acidentalmente, não há como obter outra.

Prática

Implantação simples do EBS

Antes de fazer nossa implantação complexa, podemos fazer uma implantação simples do EBS para nos familiarizarmos.

AWS Elastic Beanstalk é uma maneira de lançar uma aplicação na nuvem sem precisar configurar manualmente os recursos subjacentes, como o VPC, servidor da web e banco de dados. É muito fácil e rápido ter uma aplicação em execução no AWS ELB e é uma boa maneira de se familiarizar com a AWS.

image-5

Vá para a página inicial da AWS e crie uma nova conta se você ainda não tiver uma.

image-6

Depois, acesse Services e, em seguida, ElasticBeanStalk, em "Compute".

image-7

Isso o levará à página inicial do EBS. Após isso, avance e clique em Create New Application e depois dê um nome e descrição para sua aplicação.

image-8

Você pode, então, clicar em Create New Environment e depois selecionar Web server environment.

image-9

Nesta página, selecione Node.js como a plataforma e use o código da aplicação de exemplo. Todo o resto pode ser deixado como padrão.

Eu não tive sorte ao implantar a aplicação diretamente daqui. Então, vamos clicar em Configure more options para configurar o projeto um pouco mais.

image-10

Clique no card de rede na parte inferior da página e certifique-se de que o VCP padrão está sendo usado junto com a sub-rede padrão marcada.

Depois, clique no card Instances e certifique-se de que a caixa de grupos de segurança padrão esteja marcada.

image-11

É isso. Agora, podemos clicar em Create environment para lançar nossa aplicação.

Se funcionou, você deve ver o ambiente lançado com sucesso na sua tela.

image-12

Se você clicar no URL, poderá ver sua aplicação implantada.

image-13

Parabéns por implantar uma aplicação na nuvem da AWS!

Importante: certifique-se de excluir depois para não ser cobrado por usar a AWS.

Para excluir, simplesmente clique em Terminate Environment em Actions. Isso excluirá a aplicação junto com todos os recursos subjacentes.

image-14

Agora, podemos passar para a configuração complexa.

Configuração do VPC

Primeiro, podemos ir para o painel de controle do VPC, que está na seção Network & Content Delivery.

image-15

Você deve estar na tela de dashboard do VPC. Lá, você pode criar um VPC com o botão Launch VPC Wizard (que é um pouco mais fácil), mas eu mostrarei como configurá-lo do zero (que é um pouco mais difícil), mas dará a você uma melhor compreensão de como um VPC funciona.

Primeiro, clique na aba VPCs e clique no botão Create VPC, que levará você a uma página semelhante a esta.

image-16

Podemos nomear o VPC como VPC 3.

Podemos definir o bloco CIDR para 10.11.0.0/16. Se você se lembra das seções de Teoria de VPC e sub-rede, isso significa que os dois primeiros octetos são o prefixo da rede e os últimos dois octetos são o endereço do host. Eles estão disponíveis para nossa utilização.

Tenancy significa que o VPC estará em seu próprio hardware dedicado ou não. Há uma percepção de que a Tenancy dedicada é mais segura ou tem melhor desempenho, mas não há dados para sugerir isso.

A Tenancy padrão (em inglês, default) significa que seu VPC compartilhará o hardware subjacente com outros usuários da AWS, mas será isolado deles através de software.

Depois disso, podemos clicar em Create VPC, finalizando nossa configuração do VPC.

Configuração de sub-redes

A seguir, configuraremos as sub-redes. Podemos começar clicando na aba Subnets e clicar em Create subnet.

Vamos primeiro criar nossa sub-rede pública, assim:

image-17

10.11 é nosso prefixo de rede inalterável da nossa VPC, o que faz com que .1 também faça parte do prefixo da rede, já que a máscara de sub-rede é /24 e .1 é também o identificador dessa sub-rede.

O último octeto, então, serve como endereço do host, o que significa que esta sub-rede pode ter qualquer endereço entre 10.11.1.0 - 10.11.1.255.

Depois disso, podemos clicar em Create, o que criará a sub-rede e a listará sob as sub-redes.

Passemos para nossa sub-rede privada:

image-18

Ela é configurada de maneira similar à sub-rede pública, com a principal diferença sendo que a terceira casa decimal é .2 ao invés de .1. Também precisamos especificar uma zona de disponibilidade para fazer essa sub-rede funcionar com nosso banco de dados.

Então, basicamente, 10.11 é o prefixo de rede que obtivemos da VPC. .2 é a terceira casa decimal e o identificador único para esta sub-rede. O último octeto, .0, são os endereços IP disponíveis entre 0-255.

Isso significa que esta sub-rede pode ter qualquer endereço IP de 10.11.2.0 - 10.11.2.255.

Se você comparar isso com nossa sub-rede pública, que tem um intervalo de endereços IP de 10.11.1.0 -10.11.1.255, ficará muito mais claro qual é o padrão para configurar a sub-rede.

Implantar um banco de dados na AWS requer 2 sub-redes em diferentes zonas de disponibilidade, então você pode configurar a segunda assim:

image-19

Gateways de internet e tabelas de roteamento

Tabelas de roteamento são essencialmente roteadores e determinam como e para onde o tráfego é direcionado.

Agora, podemos criar um gateway de internet que anexaremos à nossa sub-rede pública.

image-20

Como todos os gateways de internet funcionam da mesma maneira, só precisamos definir o nome. Antes de podermos anexar este gateway de internet à nossa sub-rede, precisamos primeiro configurar a tabela de roteamento.

Podemos ir para a aba Route Tables e clicar em Create route table.

Só temos que definir o nome e associá-la à VPC. Podemos associá-la à VPC 3 e então clicar em criar.

image-21

Uma vez feito isso, podemos anexar nosso gateway de internet a essa VPC. Vamos voltar para a aba do gateway de internet, clicar no botão Actions e, depois, em Attach to VPC.

Para a opção de anexar, basta selecionar a VPC 3.

Em seguida, podemos voltar à nossa tabela de roteamento que configuramos e adicionar uma rota. Podemos adicionar a rota assim.

image-22

Isso está dizendo que, se for feita uma solicitação, a tabela de roteamento primeiro verifica se a rota é para uma rota local 10.11.0.0/16. Caso contrário, encaminhamos essa solicitação para o gateway de internet para todas as outras rotas que são representadas por 0.0.0.0/0.

Então, podemos clicar na aba de associações de sub-rede e depois no botão Edit subnet associations.

image-23

Queremos apenas que a sub-rede pública esteja associada a essa tabela de roteamento. Então, marcamos apenas essa e podemos clicar em Save.

Não podemos nos esquecer das nossas sub-redes privadas. Basta criar outra tabela de roteamento e associar as sub-redes privadas a ela da mesma maneira que fizemos para a sub-rede pública. Não adicione um gateway de internet, apenas deixe a tabela de roteamento para alvos locais.

Grupos de segurança

Grupos de segurança são essencialmente firewalls que filtram o tráfego de entrada e saída.

Precisamos configurar os grupos de segurança para trabalhar com essa configuração. Clique na aba de Security Groups e clique em Create security group.

Criar o grupo de segurança é muito fácil. Podemos apenas definir o nome e a descrição e associá-lo à nossa VPC 3.

Depois de criar os grupos de segurança, clique em Edit inbound rules.

image-24

Em seguida, podemos configurar as regras de segurança assim:

image-25

Primeiro, temos o SSH que usamos para fazer login na nossa instância do Ec2 a partir do nosso computador pessoal. Deixei a origem como 0.0.0.0/0, porque não quero colocar meu endereço IP pessoal, mas, em uma aplicação real, você vai querer colocar seu próprio endereço IP aqui.

Depois disso, temos a porta normal 80 e a porta 443, que permitem o tráfego normal pela internet. ::/0 permite todo o tráfego IPv6 junto com IPv4.

Lançando uma instância do EC2 (computador em nuvem)

Primeiro, vamos ao painel do EC2 e clicamos em Launch instance. Em seguida, podemos selecionar o Amazon Linux AMI como o sistema operacional.

image-26

Então, para permanecer na camada gratuita, selecione a opção t.2 micro para o tipo de instância.

No terceiro passo, temos que configurar os detalhes da instância, o que podemos fazer assim:

image-27

Para a rede, podemos selecionar nossa VPC 3 e, para nossa sub-rede, podemos selecionar nossa sub-rede pública. Como este é nosso servidor da web, queremos que ele esteja em nossa sub-rede pública anexada a um gateway de internet.

Adicionar tags e adicionar armazenamento podem ser deixados como padrão.

Para a segurança, certifique-se de adicionar o grupo de segurança do servidor da web que configuramos na última seção.

Isso vai gerar um pop-up para oferecer um par de chaves. Podemos seguir em frente e selecionar criar um par de chaves. Em seguida, podemos baixar esse par de chaves.

image-28

Se feito corretamente, você deverá ver isto na sua tela:

image-29

Depois disso, nossa instância é lançada e está disponível para acessarmos via SSH. Podemos acessar nossa instância com o comando:

ssh -i “keypair.pem” ec2-user@public-ip-address

Configuração do banco de dados

Vamos agora configurar o banco de dados. Podemos começar indo até a aba RDS na seção Databases, em Services. Isso nos levará ao dashboard RDS Database.

image-30

Antes de podermos criar um banco de dados, temos que criar primeiro um grupo de sub-rede. Para começar, podemos ir até a aba de grupos de sub-rede e clicar em Create db subnet group.

Um grupo de sub-rede de bancos de dados serve para proteger contra qualquer tipo de falha total do servidor ou exclusão acidental. É por isso que ele abrange 2 zonas de disponibilidade. No caso remoto de um servidor falhar completamente em uma zona de disponibilidade, seu banco de dados ainda estará bem. É extremamente improvável que os dois servidores falhem completamente em 2 zonas de disponibilidade diferentes ao mesmo tempo.

Primeiro, definimos o nome e a descrição. Depois, associamos nossa VPC 3 ao grupo de sub-rede. Após isso, podemos adicionar nossas sub-redes.

image-31

As sub-redes serão listadas sob a zona de disponibilidade onde as configuramos, na seção anterior. Depois, podemos apenas clicar em Create.

Depois de criar o grupo de sub-rede, estamos prontos para criar nosso banco de dados real.

Podemos primeiro selecionar a opção elegível para o nível gratuito no final.

image-32

Em seguida, clicamos em Next. Podemos deixar todas as outras configurações na próxima página com as opções padrão. Certifique-se de lembrar do nome de usuário e senha definidos aqui.

Na próxima página, podemos definir a VPC como nossa VPC 3, o grupo de sub-rede para o que acabamos de configurar.

Certifique-se também de deixar "Public acessibility" marcado como não. Por razões óbvias de segurança, não queremos que nossa aplicação esteja disponível na internet.

Todo o resto pode ser deixado como padrão. Configuraremos nossos grupos de segurança do banco de dados em um segundo.

image-33

Agora, podemos clicar em Create database e criar os grupos de segurança do banco de dados enquanto o banco de dados está sendo criado.

Podemos ir até a aba de grupos de segurança no dashboard da VPC e criar um grupo de segurança, como vimos anteriormente. Para as regras de entrada, podemos limitá-las ao intervalo CIDR do nosso servidor da web, com a porta configurada para a porta padrão 5432 do PSQL.

image-34

Clique em Create e estamos prontos para adicionar isso ao nosso banco de dados.

Para adicionar este novo grupo de segurança, podemos ir até o banco de dados no painel de controle do banco de dados. Depois, clique no botão Modify.

Depois disso, podemos apenas selecionar o grupo de segurança que acabamos de configurar na seção de rede e segurança.

Uma pergunta que você pode ter agora é como se conectar ao nosso banco de dados se ele não é publicamente acessível na internet.

A maneira de se fazer isso é, primeiro, acessando via SSH nossa instância do Linux e depois se conectanado ao nosso banco de dados a partir dessa instância sobre a porta TCP do PSQL, que configuramos na nossa tabela de rotas.

image-35

Para testar isso, podemos acessar via SSH nossa instância do EC2 da mesma maneira vista acima. Em seguida, podemos instalar o psql com o comando:

sudo amazon-linux-extras install postgresql9.6

Depois, podemos nos conectar ao banco de dados psql com o seguinte comando:

psql -d nome-do-bd -h nome-do-host -p porta -U nome-de-usuário

Se conectado com sucesso, você verá o nome do seu banco de dados seguido de uma seta.

image-36

Configuração do projeto do React e do Node

Aqui, vou abordar uma configuração de exemplo com React e node/express. A primeira coisa a fazer é executar o comando npm run build, que gerará uma build de produção de sua aplicação em um diretório chamado build.

Observação: certifique-se de que todas as rotas do localhost na sua versão de build sejam alteradas para o IP público. Isso é provavelmente verdade para autenticação. Todo o resto pode ser deixado como está.

Corte e cole todo este diretório build em um servidor node/express. Depois, defina um caminho para ele, conforme mostrado abaixo.

....
//servidor express

app.use(express.static(path.join(__dirname, 'build')));

if(process.env.NODE_ENV === 'production') {
  app.get('/*', function (req, res) {
   	res.sendFile(path.join(__dirname, 'build', 'index.html'));
  });
}

....

A primeira função é como servimos os arquivos estáticos da nossa aplicação do React (os arquivos JS, CSS, PWA).

A segunda função verifica se o ambiente é de produção e, então, serve o principal arquivo HTML do React.

Essa abordagem mantém nosso roteamento do lado do client intacto. Por exemplo, na nossa build de desenvolvimento podemos usar rotas como /post/22 e isso será roteado corretamente para http://localhost:3000/post/22.

Depois disso, basta fazer a implantação do projeto do React Express em um repositório do Github.

É isso. Depois, podemos implantar essa aplicação do React Express em um servidor Linux.

Implantando o projeto na instância AWS EC2

Agora, estamos prontos para implantar nosso projeto. Primeiro, use o SSH na sua instância EC2 com o Gitbash por meio do seguinte comando:

ssh -i "keypair.pem" ec2-user@endereco-ip-publico

A próxima coisa que precisamos fazer é instalar o git, com o comando:

sudo yum install git

Então, podemos clonar o projeto no servidor com o comando

sudo git clone link-to-repo

Depois de fazer isso, você deve conseguir ver os arquivos do seu projeto fazendo cd no diretório.

image-62

Ainda não terminamos. Precisamos instalar o node e o npm, porque queremos instalar as dependências do nosso projeto. Primeiro, precisamos instalar o gerenciador de versões do node (NVM), que permitirá instalar o node e o npm. Podemos instalar o nvm assim.

sudo curl https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

Isso instalará o nvm, que podemos usar para instalar o node e o npm. Para fazer isso, basta listar as versões do node disponíveis para download e instalar a mais estável.

Comando para listar versões do node
nvm ls remote

Comando de instalação
nvm install version-of-node

Depois de instalar o npm e o node, se você tentar executar npm install no diretório do projeto, receberá um erro de permissão negada.

image-63

Você pode executar o comando abaixo para dar permissão de escrita no diretório. O comando abaixo dá muito mais do que apenas permissões de escrita, mas configurar permissões no Linux está fora do escopo deste tutorial.

Digite sudo chmod 777 no diretório.

Aqui está um link para um tutorial se você quiser saber mais sobre o chmod (em inglês).

Depois disso, seus módulos do npm devem instalar normalmente com o comando normal npm install.

Então, você pode simplesmente executar sua aplicação com o comando npm start, que iniciará seu servidor do node e servirá seu projeto do React como arquivos estáticos.

O problema é que o projeto só rodará nas portas não tradicionais, como 5000 ou 3000, ou qualquer porta que você estiver usando no localhost. Se você tentar a abordagem ingênua de apenas mudar a porta para a porta 80 no servidor, receberá um erro de permissão negada.

image-64

Para corrigir isso, usaremos o nginx.

nginx

Você pode estar se perguntando por que estamos usando nginx se já temos o node. É possível usar nginx como um servidor de http, mas usaremos o nginx como um proxy reverso, o que manterá o node como o servidor http real.

A configuração ficará assim.

image-68

Os benefícios de se fazer isso são:

  • O nginx atua como um balanceador de carga em nível de aplicação
  • Ajuda o node com desempenho e confiabilidade
  • Melhora a segurança
  • Previne ataques DoS

Aqui está um diagrama que mostra um proxy regular versus um proxy reverso.

image-69

Em um proxy regular, um client da web pode enviar e receber dados de vários servidores da web. Em um proxy reverso, um único servidor da web pode enviar e receber dados de vários clients da web.

Agora, vamos para a nossa instância do EC2 e vamos usar o ssh nela.

A primeira coisa que precisamos fazer é instalar o nginx. A Amazon Linux AMI 2 já vem com o nginx. Então, você pode instalar assim:

sudo amazon-linux-extras install nginx1.12

Depois, podemos acessar o diretório do nginx com cd /etc/nginx

Podemos editar o arquivo de configuração do nginx com o comando sudo nano nginx.conf

Isso abrirá o arquivo nginx.conf no editor sudo nano.

image-65

Podemos adicionar este código à rota de localização do home

image-66

Basicamente, estamos dizendo para definir a build do react como a rota root. Defina o arquivo index.html como o índice principal. Finalmente, em cada solicitação subsequente, sirva o mesmo arquivo index.html.

Isso porque o React é uma aplicação de página única e, literalmente, um único arquivo html. Então, para possibilitar navegar dentro da aplicação do React, precisamos servir esse mesmo arquivo html novamente em caso de erros.

Em seguida, também podemos configurar o nginx para lidar com nossas rotas da API.

image-67

Isso é, na maior parte, código boilerplate, mas a propriedade a ser observada é o proxy_pass, que é nosso IP público e a porta não padrão.

Esse endereço IP será então enviado por proxy para a porta padrão 80, o que nos permitirá acessar o site normalmente.

Versão copiável do código:

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  localhost;


        # Carrega os arquivos de configuração para o bloco de servidor padrão.
        include /etc/nginx/default.d/*.conf;


        location /api/ {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass http://10.0.1.187:3000;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;

        }

Depois disso, basta salvar e sair do editor.

Também precisamos reiniciar o nginx para que as alterações tenham efeito. Fazemos isso com sudo systemctl restart nginx.

Isso é tudo de que você precisa fazer para ter o nginx como proxy reverso. Sua aplicação, agora, poderá rodar na porta 80 normalmente.

PM2

O PM2 é um gerenciador de clusters e nos permite rodar nossa aplicação automaticamente e também reiniciar automaticamente se ela travar.

Vamos nos conectar novamente à nossa instância via ssh e instalar o PM2

npm install pm2 -g

A flag -g é importante porque instala o PM2 globalmente. Isso é crucial, porque é isso que permite que o PM2 faça seu trabalho.

Se pensar a respeito, se o PM2 fosse instalado localmente, ele travaria quando nossa aplicação travasse. Ou seja, não daria certo. Instalamos globalmente para que ele fique fora do nosso projeto e possa reiniciar o projeto se ele travar.

Você pode rodar o PM2 no seu projeto com pm2 start app.js -i max

Isso iniciará o projeto com o número máximo de núcleos. Isso é importante porque o node é single threaded e usar todos os núcleos maximiza o desempenho.

Se feito com sucesso, você deve ver uma página que se parece com esta.

image-70

Aqui estão alguns outros comandos úteis para o PM2

pm2 list: lista todos os processos em execução

pm2 stop app 0: para a aplicação com id 0

pm2 delete app 0: exclui a aplicação com id 0

pm2 restart app 0: reinicia a aplicação com id 0

pm2 start app.js -i max: inicia app.js com o número máximo de threads disponíveis

É isso! Obrigado pela leitura e parabéns se você leu todo o tutorial – isso não é uma tarefa fácil.

Conecte-se com o autor no Twitter para mais atualizações sobre futuros tutoriais.