# Deploy
## Acesso com ssh
Execute o seguinte comando no terminal de seu computador (Linux/MacOS):
```
ssh-keygen -t rsa -b 4096
```
Dê um nome para sua nova chave quando for perguntado em "Enter file in which to save the key (/Users/seu_nome_de_usuário/.ssh/id_rsa):" como /Users/seu_nome_de_usuário/.ssh/chaveGCloud, por exemplo. **É importante salvar a chave no diretório .ssh**. Para as demais perguntas pode simplesmente apertar enter em todas e aceitar as configurações padrão.
No **Google Cloud Platform** na página que lista todos os compute engines disponíveis, clique no nome de sua instância exemplo(felipe-deploy) e após ser redirecionado para a próxima tela clique em editar na barra superior do menu e copie e cole o conteúdo de sua chave impresso pelo comando:
```bash
cat ~/.ssh/chaveGCloud.pub
```






Agora em seu terminal execute:
```=
eval $(ssh-agent)
ssh-add /Users/seu_nome_de_usuário/.ssh/chaveGCloud
```
Finalmente acesse seu servidor por ssh:
```bash
ssh ip_do_seu_servidor
ssh 34.95.240.65 #exemplo
```
## Instalando dependências necessárias (dentro do servidor)
Para começar a disponibilizar todos os pacotes que necessitaremos para garantir a funcionalidade de nosso servidor temos que primeiro atualizar suas referências para conseguir encontrar os mesmos para download. **Importante: tudo que virá a seguir será executado em seu servidor após estabelecer a conexão ssh.**
```bash
sudo apt update
```
Com este processo concluído agora podemos baixar o nginx e iniciar seu serviço:
```bash=
sudo apt install nginx
sudo service nginx restart
```
Agora se tentarmos acessar o ip de nosso servidor por uma aba anônima devemos ser apresentados à seguinte tela:

Devemos também instalar o docker e docker-compose:
```bash=
sudo apt install docker.io docker-compose
```
O ideal agora é criar um novo usuário deploy como boa prática e definimos uma senha para ele. Para as demais informações podemos simplesmente apertar enter até finalizar o processo.
```bash=
sudo adduser deploy
```
Vamos dar a este usuário permissão de sudo e docker:
```bash=
sudo usermod -aG sudo deploy
sudo usermod -aG docker deploy
```
Agora vamos também copiar as chaves de acesso ssh para nosso usuário deploy e dar as permissões corretas de acesso às chaves para este usuário:
```bash=
sudo mkdir -p /home/deploy/.ssh
sudo cp ~/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh/
```
Assim na próxima vez que estabelecermos uma conexão ssh a nosso servidor já podemos nos conectar com o usuário correto. Então vamos sair do servidor com o comando:
```bash
exit
```
E nos reconectamos ao servidor com:
```bash
ssh deploy@ip_do_seu_servidor
ssh deploy@34.95.240.65 #exemplo
```
## Configuração do nginx
Vamos editar nosso arquivo de conexão do nginx para atualizar a porta que utlizaremos de nosso frontend:
```bash=
sudo nano /etc/nginx/sites-available/default
```
Podemos apagar todo o contéudo que existe dentro do objeto location/ e substituí-lo pelo seguinte:
```
location / {
proxy_pass http://localhost: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;
}
```
Onde **3000** será mantido ou substituído pela porta utilizada por seu frontend.
Devemos também substituir o valor da variável servername pelo seu domínio correto:
```
server_name seu_nome.felipecabral.dev;
```
Agora podemos fechar a edição do arquivo com ctrl+x e confirmar a gravação do arquivo.
Devemos agora replicar a configuração para nosso backend criando um novo arquivo para ele, copiando nosso arquivo default como base:
```bash
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/api
```
Agora vamos editar este arquivo também:
```bash
sudo nano /etc/nginx/sites-available/api
```
Vamos modificar as linhas:
```
listen 80 default_server;
listen [::]:80 default_server;
```
e deixa-las sem definição de default_server:
```
listen 80;
listen [::]:80;
```
Vamos substituir o valor da variável servername pelo seu domínio correto:
```
server_name http://api.seu_nome.felipecabral.dev;
```
E nosso proxy_pass dentro de server_name para:
```
proxy_pass http://localhost:3333;
```
Onde **3333** será mantido ou substituído pela porta utilizada por seu backend. Caso esteja utlizando nosso projeto desenvolvido ao longo das aulas pode manter a porta 3333.
Agora precisamos habilitar a configuração da api fazendo um link simbólico que aponta para este arquivo na pasta /etc/nginx/sites-enabled:
```bash
sudo ln -s /etc/nginx/sites-available/api /etc/nginx/sites-enabled/api
```
E finalmente testamos se a sintaxe das nossas configurações está ok com:
```bash
sudo nginx -t
```
Em caso negativo, procure por erros e corrija-os nos arquivos. Se tudo estiver certo pode então reiniciar o serviço do nginx para que as alterações entrem em vigor:
```bash
sudo service nginx restart
```
## Docker-compose
Agora vamos baixar algum projeto para fazer nosso deploy. Podemos utilizar se necessário o projeto abordado ao longo de nossas aulas:
```bash=
git clone https://github.com/fkbral/app-deploy-class ~/app
cd ~/app
git checkout aula12
```
Vamos agora configurar nossos arquivos de variáveis ambiente do backend e frontend a partir de nossos arquivos .env.example:
```bash=
cp ~/app/backend/.env.example ~/app/backend/.env
```
E edite o arquivo com nano, caso necessário:
```bash
nano ~/app/backend/.env
```
Fazemos o mesmo para nosso frontend:
```bash
cp ~/app/frontend/.env.example ~/app/frontend/.env
```
E caso estejam utilizando o projeto das aulas faça a seguinte alteração com nano:
```bash
nano ~/app/frontend/.env
```
```.env
REACT_APP_API_URL=http://34.95.240.65:3333
```
ou
```.env
REACT_APP_API_URL=api.seunome.felipecabral.dev:3333
```
Agora devemos acessar a pasta que contém nosso docker-compose.yml. No caso do projeto das aulas este seria:
```
cd ~/app/backend
```
E finalmente executamos:
```
docker-compose up
```
Agora se acessarmos novamente o endereço do nosso servidor pelo navegador utilizando http podemos acessar finalmente nossa aplicação no endereço **http://ip_do_seu_servidor**
## Matendo a aplicação no ar
Atualmente nossa aplicação pode sair do ar caso o servidor seja reiniciado ou diante a ocorrência de erros. Então vamos utlizar um gerenciador de processos disponível como um pacote npm. Vamos dar um ctrl+c no terminal e parar o processo iniciado pelo docker-compose e vamos instalar o yarn:
```bash=
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 update && sudo apt install yarn
```
Agora instalaremos o pm2:
```bash
sudo yarn global add pm2
```
E devemos disponibilizar os pacotes do yarn globalmente para nosso terminal editando o arquivo .bashrc e adicionando uma linha em seu início com o seguinte valor:
```bash
echo "PATH=$PATH:$(yarn global bin)" >> ~/.bashrc
```
Agora podemos reiniciar as configurações do nosso terminal com:
```bash
source ~/.bashrc
```
Agora temos o comando pm2 disponível e podemos adicionar o processo do docker-compose como um serviço no pm2
```bash=
cd ~/app/backend
pm2 start "docker-compose up"
```
Podemos visualizar que o processo foi adicionado com:
```bash
pm2 list
```
Temos até a opção de visualizar o consumo em tempo real de todos nossos processos rodando do pm2 com o comando:
```bash
pm2 monit
```
Agora devemos garantir que o pm2 reinicie junto com nosso servidor e para isso executamos:
```bash
pm2 startup systemd
```
Após executar o comando, copie o seguinte o comando que será gerado em tela a partir do "sudo" segundo a foto:

Agora cole-o no seu terminal e execute-o.
Pronto, agora seu pm2 iniciará automaticamente com seu servidor. Agora basta salvar a lista de processos atual disponível na lista do pm2 para ser carregado em seu início com o comando:
```bash
pm2 save
```