diff --git a/Diretorias/Diretoria Projetos/deploy/heroku/explicacao.md b/Diretorias/Diretoria Projetos/deploy/heroku/explicacao.md deleted file mode 100644 index 0cc4e242..00000000 --- a/Diretorias/Diretoria Projetos/deploy/heroku/explicacao.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -order: 3 -icon: rocket -label: "O que é Heroku ?" ---- - - - - -Heroku é uma plataforma de deployment de website, desenvolvidos em quase todos frameworks mais famosos utimamente, ela automaticamente analisa o repositório e verifica a linguagem que você está utilizando, e já faz o setup completo, facilitando uma das principais e mais demoradas atividades de um projeto de website. O Heroku roda um container docker com seus scripts de inicialização. Isso significa que é necessário que o seu projeto seja um servidor, ou seja, que ele tenha uma porta para ser acessado, e que ele seja capaz de responder a requisições. Sendo assim, é ideal para api's, mas não para servir _assets estáticos_ (como os gerados numa aplicação React comum). - -!!! -O Heroku, na ultima atualização dessa documentação, não possui plano gratuito, logo utilizamos self-hosting para o back-end na Struct. -!!! diff --git a/Diretorias/Diretoria Projetos/deploy/index.yml b/Diretorias/Diretoria Projetos/deploy/index.yml index 513e0bf8..e082631a 100644 --- a/Diretorias/Diretoria Projetos/deploy/index.yml +++ b/Diretorias/Diretoria Projetos/deploy/index.yml @@ -1,2 +1,2 @@ -icon: rocket -label: Deploy \ No newline at end of file +icon: share +label: Deploy diff --git a/Diretorias/Diretoria Projetos/deploy/netlify/index.yml b/Diretorias/Diretoria Projetos/deploy/netlify/index.yml deleted file mode 100644 index 10096fdd..00000000 --- a/Diretorias/Diretoria Projetos/deploy/netlify/index.yml +++ /dev/null @@ -1,5 +0,0 @@ -icon: rocket -label: Netlify - -# Ultima atualização: 23/09/2023 -# Autor(es): Artur Padovesi \ No newline at end of file diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting/explicacao.md b/Diretorias/Diretoria Projetos/deploy/self_hosting/explicacao.md new file mode 100644 index 00000000..45010905 --- /dev/null +++ b/Diretorias/Diretoria Projetos/deploy/self_hosting/explicacao.md @@ -0,0 +1,20 @@ +--- +order: 3 +icon: rocket +label: "Explicando nosso self hosting" +--- + + + + +## O que é self hosting? + +Self-hosting, também conhecido como auto-hospedagem, é um conceito em tecnologia que se refere à prática de hospedar e gerenciar seus próprios serviços, aplicativos ou plataformas em infraestrutura própria, em vez de utilizar serviços e plataformas de terceiros ou fornecedores externos. + +Em outras palavras, quando você opta por self-hosting, você é responsável por configurar, administrar e manter todos os aspectos do serviço ou aplicativo que está executando. + +## Nossa estrutura + +No momento, pagamos por um servidor no **DigitalOcean**, que é um serviço de cloud computing, ou seja, uma plataforma que usa a conectividade da internet para hospedar e prover recursos, programas e informações em nuvem, e usamos ssh para acessá-lo e fazê-lo rodar exatamente o que queremos. + +Além disso, usamos Docker para poder isolar e rodar vários servidores na mesma máquina. Para levar o tráfego que chega em nossa máquina para o container correto, usamos o [Traefik v2](https://doc.traefik.io/traefik/) como [proxy reverso](https://pt.wikipedia.org/wiki/Proxy_reverso). Isso é necessáro pois temos vários domínios apontando para o nosso servidor (structej.unb.br, marks.com.br). diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting/front/fazendo.md b/Diretorias/Diretoria Projetos/deploy/self_hosting/front/fazendo.md new file mode 100644 index 00000000..dce85586 --- /dev/null +++ b/Diretorias/Diretoria Projetos/deploy/self_hosting/front/fazendo.md @@ -0,0 +1,180 @@ +--- +order: 1 +icon: rocket +label: "Fazendo deploy de frontend" +--- + + + + +## Considerações + +Considerando que nenhum framework, e nem SSR, está sendo usado, a aplicação React não inclui servidor. No ambiente de **desenvolvimento** são usadas **ferramentas** (como vite, create-react-app, etc) para servir a aplicação na porta determinada (na Struct determinamos como 3000), mas no deploy utilizamos o Express, um servidor web que pode ser usado para servir arquivos estáticos, como imagens, css, js, etc. Sendo assim, após fazer o build da aplicação React, o Express é que estará servindo os _assets_ estáticos na porta definida. + +!!!danger Errado +Estamos usando Express para fazer o deploy! +!!! + +## Configurando o projeto + +!!! +Considere a [branch production do projeto jeira](https://github.com/StructCE/jeira-frontend/tree/production) como um exemplo. +!!! + +## Criando a branch production + +Crie a branch `production` a partir da `main` ou da `development`. **Esteja** localmente **na** branch **`production`** + +1. Criar um arquivo `.dockerignore` para garantir que o container gere certos arquivos, ao invés de usar as suas locais. É importante retirar possíveis fontes de problemas. Colocar o seguinte conteudo dentro do arquivo criado: + +```dockerignore +/node_modules +/dist +/build +``` + +2. Adicione o pacote `express` ao projeto. Crie um arquivo `sever.js` com o seguinte conteúdo: + +```js +const express = require("express"); +//chamamos o express para o arquivo + +const { resolve } = require("path"); +//para garantir que pegaremos o path exato + +const app = express(); +//criamos uma aplicação com o express + +app.use("/static", express.static(resolve(__dirname, "./build/static"))); + +app.use( + "/asset-manifest.json", + express.static(resolve(__dirname, "./build/asset-manifest.json")) +); + +app.use( + "/favicon.ico", + express.static(resolve(__dirname, "./build/favicon.ico")) +); + +app.use( + "/index.html", + express.static(resolve(__dirname, "./build/index.html")) +); + +app.use( + "/manifest.json", + express.static(resolve(__dirname, "./build/manifest.json")) +); + +app.use( + "/robots.txt", + express.static(resolve(__dirname, "./build/robots.txt")) +); + +app.use("*", express.static(resolve(__dirname, "./build"))); +//serve para pegarmos os itens de forma estática e servirmos o build + +app.listen(80, (err) => { + //usaremos a porta que o heroku definir ou a 300 + if (err) { + return console.log(err); + } + //caso tenha um erro vai retornar o erro na callback + console.log("Deu bom!"); + //no mais, esse console.log aparecerá na tela +}); +``` + +!!!warn +Eu sei que existe uma maneira melhor de fazer isso, mas desse jeito funciona, e como nossa aplicação é um SPA, então **não funciona** só fazer o seguinte: + +```js +app.use("*", express.static(resolve(__dirname, "./build"))); +``` + +Pois o `index.html` pede pelos arquivos `favicon.ico`, `static/*.js` e `static/*.css`. Nosso servidor serviria recursivamente o diretório inteiro da build para cada uma das requisições pedindo um único arquivo. + +Além disso, ter um rota _catch all_ (`*`) é necessário pois, como temos um SPA, queremos que `/` e `/users/profile/1` retornem os mesmo arquivos (todos os da build). + +!!! + +3. Adicione o arquivo `start.sh` com o comando que deve ser rodado ao inicializar o container: + +```bash +#!/bin/bash +bun server.js +``` + +4. Adicionar o Dockerfile de frontend: + +```dockerfile +# Imagem de Origem +FROM oven/bun as build + +RUN apt-get -y update + +# # if using Create React App, uncomment: +# RUN apt-get -y install nodejs +# # needed so build using react-scripts works + +WORKDIR /app + +COPY bun.lockb . +COPY package.json . +RUN bun install + +COPY . . +RUN bun run build + + +FROM oven/bun as start + +WORKDIR /app + +# copying only needed files to end image +COPY --from=build /app/build/. ./build +COPY --from=build /app/server.js ./server.js +COPY --from=build /app/start.sh ./start.sh + +RUN chmod +x ./start.sh +CMD ["./start.sh"] +``` + +!!! +Estamos usando bun pra instalar e rodar as coisas porque, no momento, bun é mais rápido que npm, e npm era lento que incomodava fazer a build do projeto. +!!! + +### Mudando as urls de localhost + +!!! +A aplicação React usa urls locais para acessar a API, por exemplo, `http://localhost:3333/api/v1`. Essas urls devem ser alteradas para as urls de produção, por exemplo, `https://api.struct.com.br/api/v1`.É possível fazer isso usando variáveis de ambiente, mas no momento deve ser trocado manualmente, como no nosso repositório de exemplo (talvez esse gitbook esteja desatualizado em relação ao repositório, verifique). +!!! + +### Mudando o `index.html` + +1. Alterar o arquivo `index.html` para conter informações corretas sobre a aplicação, bem como os metadados. +2. Criar um `robots.txt`, para ajudar os mecanismos de busca, além indexar o site conforme necessario. +3. Colocar o título correto, colocar descrição, mudar o favicon e a linguagem para pt-BR. + +## Criando a imagem + +[Cr] + +## Criando container + +1. Atualize o repositório de docker_compose da Struct com o seguinte comando: + +```bash Terminal +git pull +``` + +2. Crie uma pasta com o nome do projeto. +3. Modifique o template de `docker-compose.yml` do Traefik com os nomes que podem ser usados para identificar o projeto nos logs, caso ocorra algum erro. +4. Definir a imagem que será usada com o valor de `image`. +5. Alterar os valores de `environment`, `restart`, `volumes`, e `networks`. +6. Crie o container usando o comando: + +```bash Terminal +`docker-compose up -d` +``` diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting/front/index.yml b/Diretorias/Diretoria Projetos/deploy/self_hosting/front/index.yml new file mode 100644 index 00000000..8556a7fd --- /dev/null +++ b/Diretorias/Diretoria Projetos/deploy/self_hosting/front/index.yml @@ -0,0 +1,4 @@ +icon: rocket +label: Frontend (SPA) +# Ultima atualização: 23/09/2023 +# Autor(es): Artur Padovesi diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting/ideia.md b/Diretorias/Diretoria Projetos/deploy/self_hosting/ideia.md new file mode 100644 index 00000000..80c61928 --- /dev/null +++ b/Diretorias/Diretoria Projetos/deploy/self_hosting/ideia.md @@ -0,0 +1,198 @@ +--- +order: 1 +icon: rocket +label: "Qual a ideia de qualquer deploy?" +--- + + + + +## Passos + +1. Apontar o domínio para o IP do nosso servidor: + - Isso deve ser feito no site que configura o domínio; + - Caso o cliente já tenha um domínio para uso interno de sua empresa, provavelmente não teremos acesso. Para gerar o certificado SSL deve ser usado nosso proxy interno (traefik), podendo tomar como exemplo o deploy do Jeira; + - Caso o cliente não tenha um domínio, será necessário que o cliente compre o domínio, e é sugerido que ele seja configurado para usar Cloudflare como proxy reverso. Com o Cloudflare é mais fácil configurar o certificado SSL; +2. Configurar o projeto no github: + - Crie uma branch `production` e faça as alterações nessa branch. Essas alterações podem ser trocar URL's, adicionar um start.sh, etc.; +3. Criar uma imagem docker com o projeto dentro. + - Para isso, é feito um **Dockerfile** que faz a **_build_** do projeto, copia arquivos necessários, instala o mínimo necessário para depois o projeto poder rodar no servidor. + - Uma imagem Docker é como uma configuração inicial para **depois** uma máquina virtual inicializada com **Docker Compose**. Sendo assim, tem sistema operacional, pacotes instalados, filesystem, etc. separados. + - É comum gerar imagens a partir de outras imagens. Por exemplo, para rodar `NodeJS` é comum se basear na imagem oficial do Node ao invés de instalar tudo na mão (Sistema Operacional, dependências do Node, etc.). +4. Criar um `docker-compose.yml` para o projeto; + - Boa parte das seções de um `docker-compose.yml` são específicas do projeto, mas a seção de labels está sendo usada para configurar o container dentro do **traefik**; + - Esse arquivo pode ter mais de um `service`, por exemplo uma aplicação Next e um banco de dados MySQL. + +## Glossário + +### Dockerfile + +Dockerfile constrói uma imagem. Uma imagem é uma "foto" de uma computador em um estado. Ela inclui arquivos, sistema operacional (geralmente é usado Alpine ou um SO extremamente leve), dependências instaladas e, finalmente, o **comando de inicialização**. + +Ao construir imagens, geralmente são usadas imagens intermediárias. + +!!!warning +Cuidado para não copiar coisas demais para a Imagem Docker. Por exemplo, `node_modules/` não deve ser copiado do local para a imagem, mas sim o `package.json` para rodar o `pnpm install` ao construir a imagem (no Dockerfile). + +Como o sistema operacional rodando dentro dele é diferente do seu, copiar arquivos instalados para a sua máquina pode criar problemas. +!!! + +==- Exemplo de Dockerfile usando bun para buildar um projeto react, e rodar um servidor express para servi-lo + +```Dockerfile +# Imagem de Origem +FROM oven/bun as build + +RUN apt-get -y update + +# # needed so react-scripts build works +# # Se seu projeto estiver usando Create React App (for legado) descomente: +# RUN apt-get -y install nodejs + +# Separando a pasta com a aplicação do resto da imagem original +WORKDIR /app + +# RUN git clone ${PROJETO_GITHUB} --depth=1 --branch production /app/ +COPY bun.lockb . +COPY package.json . +RUN bun install + +# coloque o node_modules e outras pastas a serem ignoradas no .dockerignore +# senão pode ser copiada sem querer aqui +COPY . . +RUN bun run build + +# Iniciando construção da imagem final: +FROM oven/bun as start + +WORKDIR /app + +# Copiando somente os arquivos necessários, para diminuir ao máximo o tamanho final da imagem +# Pasta com o resultado da build: +COPY --from=build /app/build/. ./build +# Pasta com o servidor express +COPY --from=build /app/server.js ./server.js +COPY --from=build /app/start.sh ./start.sh + +# Tornando o start.sh executável +RUN chmod +x ./start.sh +# declarando o comando de inicialização da imagem: +CMD ["./start.sh"] +# Como só pode existir um comando de inicialização, se queremos ter mais de um comando +# ao iniciar o container precisamos usar o start.sh +``` + +=== + +### docker-compose.yml + +Esse arquivo pode ser usado com o comando `docker-compose up` ou `docker compose up`, e deve ser usada a flag `-d` quando no servidor. Ao fazer tal coisa, ele gera um **container com** o conteúdo da **imagem**, e roda o **comando de inicialização**. + +Ele tem várias partes de configuração: + +1. `networks`: + - Declara as conexões que os containers tem. No servidor, temos uma conexão chamada `proxy` que conecta todo mundo, mas às vezes é necessário ter uma conexão interna também, para, por exemplo, conectar um app Next com seu banco de dados; + - Caso queira rodar o container localmente, deve tirar o network proxy. +2. `services`: + - É aqui que a magia acontece. + - Declare um nome para os serviços que serão rodados, coloque o nome da imagem delas (a gerada anteriormente pelo Dockerfile, ou uma da internet); + - Declare `volumes` caso queira sincronizar arquivo/diretório do container com o do computador. Isso é útil ao ter um banco de dados, ao guardar arquivos no container, etc. + +Um exemplo do projeto Jeira: + +```yml +version: "3.3" + +# `dominio.qualquer.br`,`www.dominio.qualquer.br` +# my-react-app (uniq) +# my-react-app-certresolver (uniq) +# 80 + +networks: + proxy: + external: true + +services: + my-react-app: + image: structej/projetos:my-react-app-1.0.9 + environment: + - TZ=America/Sao_Paulo + labels: + - traefik.enable=true + - traefik.docker.network=proxy + + # # http access + - traefik.http.routers.my-react-app.rule=Host(`dominio.qualquer.br`,`www.dominio.qualquer.br`) + - traefik.http.routers.my-react-app.entrypoints=web + + # # https access + + - traefik.http.routers.my-react-app-websecure.rule=Host(`dominio.qualquer.br`,`www.dominio.qualquer.br`) + - traefik.http.routers.my-react-app-websecure.entrypoints=websecure + - traefik.http.routers.my-react-app-websecure.tls=true + + # # Specify to container port + - traefik.http.routers.my-react-app-websecure.service=my-react-app-service + - traefik.http.routers.my-react-app.service=my-react-app-service + - traefik.http.services.my-react-app-service.loadbalancer.server.port=80 + + # # redirect http to https + + - traefik.http.middlewares.my-react-app-redirect-to-websecure.redirectscheme.scheme=https + - traefik.http.middlewares.my-react-app-redirect-to-websecure.redirectscheme.permanent=true + - traefik.http.routers.my-react-app.middlewares=my-react-app-redirect-to-websecure + + # # certResolver pra quando precisar gerar certificado por aqui: + # # Exemplo do jeira. Ver traefik.yml para ver a configuracao do challenge: + + - traefik.http.routers.my-react-app-websecure.tls.certResolver=my-react-app-certresolver + + restart: always + volumes: + - project_data:/app/storage/ + networks: + - proxy + +volumes: + project_data: +``` + +### IP + +IP nada mais é do que o endereço da máquina. + +Em uma metáfora: se você quer ir pra casa (website) de alguém, precisa saber qual o endereço. + +### servidor + +É um computador que **serve** clientes. Você pode fazer do seu laptop um servidor. + +Nós pagamos por um computador da DigitalOcean, para que ele fique no ar 24/7. + +### domínio + +IP serve como endereço, mas é feio. Você, como usuário, não quer ir para http://104.131.141.67/, você quer ir para o https://struct.unb.br/. + +Sendo assim, geralmente se tem/compra um domínio (que.eh.tipo.isso.com) com uma autoridade de domínio, que ela redirecionará o usuário para o IP. Se configura com a autoridade de domínio para qual IP o domínio deve redirecionar. + +### reverse proxy + +Ele intermedia a internet e o servidor. Ao invés da requisição ir direto para quem vai servi-la, passa por um intermediário. + +Esse intermediário pode configurar certificados SSL/TLS, pode redirecionar para outros servidores de acordo com o domínio, pode lidar com cache, etc. + +Na Struct, tipicamente sugerimos pagar e colocar o domínio no **Cloudflare** para que ele lide com os certificados automaticamente. Então usamos o **Traefik** dentro do nosso servidor para que ele redirecione a requisição para o container correto. Ou seja, a request acaba passando por 2 _reverse proxies_ antes de chegar no container que está rodando o servidor Rails/Express/NextJS/etc. + +https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/ + +### Traefik + +É o que usamos no nosso servidor como reverse proxy. Ele redireciona a request para o container, dependendo das rules de [cada container](https://doc.traefik.io/traefik/routing/routers/). Por exemplo, podemos colocar para redirecionar requests vindo do domínio `www.structej.com` para um container, e vindo de `reminder.structej.com` para outro. + +Também podemos configurar o [certificado SSL/TLS de cada container](https://doc.traefik.io/traefik/https/acme/) pelo nosso proxy reverso. Caso tenha acesso ao nosso servidor, veja o `docker-compose.yml` do site struct como referência, além do nosso `traefik.yml`. + +### certificado SSL/TLS + +É a diferença do http para o https (http secure). Para garantir que a conexão com o site é criptografada (e então não pode ser interceptada), se coloca um certificado no servidor. Quando o usuário acessar seu site, caso esse certificado não seja encontrado, a conexão é http e os navegadores avisam o usuário que eles não estão seguros. + +Para ter um certificado no seu site, se faz uma configuração no container (quem está de fato servindo o website) ou nos reverse proxy que receberem a conexão antes dele. Sendo assim, isso pode ser feito usando o Cloudflare, o Traefik, ou dentro do container, instalando o certificado com alguma outra ferramenta. diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting/index.yml b/Diretorias/Diretoria Projetos/deploy/self_hosting/index.yml new file mode 100644 index 00000000..7b64213c --- /dev/null +++ b/Diretorias/Diretoria Projetos/deploy/self_hosting/index.yml @@ -0,0 +1,4 @@ +icon: server +label: Self-Hosting +# Ultima atualização: 22/09/2023 +# Autor(es): Artur Padovesi e Pedro Augusto Ramalho Duarte diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting_back/como_usar.md b/Diretorias/Diretoria Projetos/deploy/self_hosting/sempre.md similarity index 55% rename from Diretorias/Diretoria Projetos/deploy/self_hosting_back/como_usar.md rename to Diretorias/Diretoria Projetos/deploy/self_hosting/sempre.md index 889c17c3..26ad8837 100644 --- a/Diretorias/Diretoria Projetos/deploy/self_hosting_back/como_usar.md +++ b/Diretorias/Diretoria Projetos/deploy/self_hosting/sempre.md @@ -1,7 +1,7 @@ --- order: 1 icon: rocket -label: "Como fazer Self-Hosting (Back-End)?" +label: "O que fazer em qualquer deploy?" --- @@ -14,12 +14,11 @@ label: "Como fazer Self-Hosting (Back-End)?" !!! 1. Crie uma branch `production`; -2. Adicione `Dockerfile` ao `.gitignore` do projeto; ## Crie a imagem Docker !!! -Não coloque Dockerfiles no repositório do projeto, utilize o repositório do GitBucket para isso. Colocar esse arquivo no projeto pode causar problemas de segurança. Muitos dos nossos Dockerfiles usam credenciais que **não devem** ser expostas. +Muitos dos nossos Dockerfiles usam credenciais que **não devem** ser expostas. Se seu Dockerfile contém algo assim, dê commit apenas em um Dockerfile.example sem as credenciais. !!! 1. Pegue o template de `Dockerfile` no GitBucket @@ -27,14 +26,13 @@ Não coloque Dockerfiles no repositório do projeto, utilize o repositório do G 3. Para construir a imagem, use o comando: ```bash Terminal -docker build -t structej/projetos:{nome_do_projeto_versão} +docker build -t structej/projetos:nome-do-projeto-vers.subv ``` !!! Várias das nossas imagens são um pull do projeto, e para isso é necessário um token de acesso no github. Para gerar esse token, pode ser seguida a [Documentação do GitHub](https://docs.github.com/pt/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-personal-access-token-classic). !!! - ## Faça o Push da imagem Docker 1. Faça login no DockerHub, usando o comando: @@ -46,23 +44,30 @@ docker login 2. Faça o push da imagem para o DockerHub, usando o comando: ```bash Terminal -docker push structej/projetos:{nome_do_projeto_versão} +docker push structej/projetos:nome-do-projeto-vers.subv ``` !!! -O `structej/projetos` é o `usuário/projeto` que enviamos a imagem de tag `{nome_do_projeto_versão}`. É importante fazer assim, pois por padrão projetos no DockerHub são públicas, então enviamos ela para um repositório que sabemos ser privado. +O `structej/projetos` é o `usuário/projeto` que enviamos a imagem de tag `nome-do-projeto-vers.subv`. É importante fazer assim, pois por padrão projetos no DockerHub são públicas, então enviamos ela para um repositório que sabemos ser privado. !!! -## Faça o docker-compose no servidor +## Faça o docker-compose + +!!!warning Como assim **no servidor**? +Lembre que **no servidor** significa que é necessário acessar o servidor por _ssh_ e rodar os comando **pelo ssh**!! +!!! !!! Os templates de `docker-compose.yml` ficam na pasta `templates` do repositório armazenado no servidor. !!! -1. Fazer as atualizações localmente; +1. Fazer as atualizações **localmente**; 2. Fazer um push para o repositório; -3. Fazer um pull no servidor; -4. Faça o pull/clone do repositório do Docker Compose, usando o comando +3. Fazer um pull **no servidor**; + +Caso não tenha o repositório localmente, + +1. Faça o pull/clone do repositório do Docker Compose, usando o comando ```bash Terminal git pull/clone @@ -83,7 +88,13 @@ Procure por coisas que podem quebrar ou requerem passos adicionais no deploy, co 1. Faça o build da imagem docker, usando o comando: ```bash Terminal -docker build -t structej/projetos:{nome_do_projeto_versão} +docker build -t structej/projetos:nome-do-projeto-vers.subv +``` + +Por exemplo: + +```bash Terminal +docker build -t structej/projetos:nome-do-projeto-1.0 ``` !!! @@ -93,14 +104,13 @@ Agora a versão da imagem docker é `versão`. Sempre incrementamos a `versão` 2. Faça o push da imagem para o DockerHub, usando o comando: ```bash Terminal -docker push structej/projetos:{nome_do_projeto_versão} +docker push structej/projetos:nome-do-projeto-vers.subv ``` ## Atualize o docker-compose no servidor -1. Mudar a propriedade `image` do serviço do projeto no `docker-compose.yml` para a versão atual da imagem docker; -2. Faça o commit das alterações; -3. Faça o push do `docker-compose.yml`; +1. Esteja no repositório gitbucket do servidor; +2. Mude a propriedade `image` do serviço do projeto no `docker-compose.yml` para a versão atual da imagem docker; ```yml Exemplo version: '3.7' @@ -109,4 +119,17 @@ services: service-we-want-to-update: image: structej/projetos:nome-projeto-x.x ... -``` \ No newline at end of file +``` + +3. Faça o commit e push das alterações; +4. Entre no servidor com **ssh**; +5. Dê um `git pull` no diretório correto, com `docker-compose.yml` alterado, e depois rode `docker-compose up -d` +6. Verifique se deu certo e o serviço está funcionando normalmente; + +### Deu errado, e agora? + +1. Dê rollback de alguma maneira pra versão anterior. Pode usar git pra voltar pro último commit, reverter o commit anterior, alterar na mão a imagem pra versão anterior, etc. + +2. Continuou dando errado? Talvez alguém tenha alterado esse arquivo anteriormente e não deu `docker-compose up -d`, e agora o problema sobrou pra você. Verifique se as variáveis de ambiente estão configuradas corretamente. + +3. Tá difícil? Verifique os commits anterirores e as alterações feitas nesse `docker-compose.yml` e tente isolar a mudança que causou o problema. diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting_back/explicacao.md b/Diretorias/Diretoria Projetos/deploy/self_hosting_back/explicacao.md deleted file mode 100644 index 3bab7882..00000000 --- a/Diretorias/Diretoria Projetos/deploy/self_hosting_back/explicacao.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -order: 3 -icon: rocket -label: "O que é Self-Hosting (Back-End) ?" ---- - - - - -Self-hosting, também conhecido como auto-hospedagem, é um conceito em tecnologia que se refere à prática de hospedar e gerenciar seus próprios serviços, aplicativos ou plataformas em infraestrutura própria, em vez de utilizar serviços e plataformas de terceiros ou fornecedores externos. Em outras palavras, quando você opta por self-hosting, você é responsável por configurar, administrar e manter todos os aspectos do serviço ou aplicativo que está executando. No momento, pagamos por um servidor no DigitalOcean, que é um serviço de cloud computing, ou seja, uma plataforma que usa a conectividade da internet para hospedar e prover recursos, programas e informações em nuvem, e usamos ssh para acessá-lo e fazê-lo rodar exatamente o que queremos. Além disso, usamos Docker para poder isolar e rodar vários servidores na mesma máquina. Para levar o tráfego que chega em nossa máquina para o container correto, usamos o [Traefik v2](https://doc.traefik.io/traefik/) como [proxy reverso](https://pt.wikipedia.org/wiki/Proxy_reverso). diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting_back/index.yml b/Diretorias/Diretoria Projetos/deploy/self_hosting_back/index.yml deleted file mode 100644 index bc1a0a27..00000000 --- a/Diretorias/Diretoria Projetos/deploy/self_hosting_back/index.yml +++ /dev/null @@ -1,5 +0,0 @@ -icon: rocket -label: Self-Hosting (Back-End) - -# Ultima atualização: 22/09/2023 -# Autor(es): Artur Padovesi e Pedro Augusto Ramalho Duarte \ No newline at end of file diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting_front/como_usar.md b/Diretorias/Diretoria Projetos/deploy/self_hosting_front/como_usar.md deleted file mode 100644 index 9aa7634a..00000000 --- a/Diretorias/Diretoria Projetos/deploy/self_hosting_front/como_usar.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -order: 1 -icon: rocket -label: "Como faz Self-Hosting (Front-End)?" ---- - - - - -## Configurando o projeto - -!!! -Considere a [branch production do projeto front-end-template](https://github.com/StructCE/react-template/tree/production) e [suas alterações](https://github.com/StructCE/react-template/compare/main...production). -!!! - -## Configurando o NGinx - -1. Criar um arquivo `nginx.conf` para configuração do NGinx na raíz do projeto. -2. Colocar o seguinte conteudo dentro do arquivo criado: - -``` Conteudo -server { - listen 80 default_server; - listen [::]:80 default_server; - root /usr/share/nginx/html; - server_name dominio.exemplo.ex www.dominio.exemplo2; - location / { - root /usr/share/nginx/html; - index index.html index.htm; - try_files $uri $uri/ /index.html =404; - } -} -``` - -3. Trocar os valores de `dominio.exemplo.ex` e `www.dominio.exemplo2` pelos domínios que o aplicação que será feito o deploy.Se o app for servido em `www.struct.com.br`, o arquivo deve conter: - -``` Exemplo -server { - listen 80 default_server; - listen [::]:80 default_server; - root /usr/share/nginx/html; - server_name www.struct.com.br; - location / { - root /usr/share/nginx/html; - index index.html index.htm; - try_files $uri $uri/ /index.html =404; - } -} -``` - -## Mudando as urls de localhost - -!!! -A aplicação React usa urls locais para acessar a API, por exemplo, `http://localhost:3333/api/v1`. Essas urls devem ser alteradas para as urls de produção, por exemplo, `https://api.struct.com.br/api/v1`.É possível fazer isso usando variáveis de ambiente, mas no momento deve ser trocado manualmente, como no nosso repositório de exemplo (talvez esse gitbook esteja desatualizado em relação ao repositório, verifique). -!!! - -## Mudando o `index.html` - -1. Alterar o arquivo `index.html` para conter informações corretas sobre a aplicação, bem como os metadados. -2. Criar um `robots.txt`, para ajudar os mecanismos de busca, além indexar o site conforme necessario. -3. Colocar o título correto, colocar descrição, mudar o favicon e a linguagem para pt-BR. - -## Criando docker image - -1. Vá para a branch production localmente. -2. Crie um arquivo chamado `Dockerfile` na raíz do projeto. -3. Atualize o url do git presente no arquivo, mudando o nome do projeto e o token de autenticação do GitHub. - -## Criando container - -1. Atualize o repositório de docker_compose da Struct com o seguinte comando: - -```bash Terminal -git pull -``` - -2. Crie uma pasta com o nome do projeto. -3. Modifique o template de `docker-compose.yml` do Traefik com os nomes que podem ser usados para identificar o projeto nos logs, caso ocorra algum erro. -4. Definir a imagem que será usada com o valor de `image`. -5. Alterar os valores de `environment`, `restart`, `volumes`, e `networks`. -6. Crie o container usando o comando: - -```bash Terminal -`docker-compose up -d` -``` \ No newline at end of file diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting_front/explicacao.md b/Diretorias/Diretoria Projetos/deploy/self_hosting_front/explicacao.md deleted file mode 100644 index 3fd557a6..00000000 --- a/Diretorias/Diretoria Projetos/deploy/self_hosting_front/explicacao.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -order: 3 -icon: rocket -label: "O que é Self-Hosting (Front-End)?" ---- - - - - -Self-hosting, também conhecido como auto-hospedagem, é um conceito em tecnologia que se refere à prática de hospedar e gerenciar seus próprios serviços, aplicativos ou plataformas em infraestrutura própria, em vez de utilizar serviços e plataformas de terceiros ou fornecedores externos. Em outras palavras, quando você opta por self-hosting, você é responsável por configurar, administrar e manter todos os aspectos do serviço ou aplicativo que está executando.Considerando que nenhum framework, e nem SSR, está sendo usado, a aplicação react não inclui servidor. No ambiente de desenvolvimento são usadas ferramentas para servir a aplicação na porta determinada (na Struct determinamos como 3000), mas no deploy utilizamos o NGinx, um servidor web que pode ser usado para servir arquivos estáticos, como imagens, css, js, etc. Sendo assim, depois que nossa aplicação react é buildada, ela é mantida pelo NGinx. \ No newline at end of file diff --git a/Diretorias/Diretoria Projetos/deploy/self_hosting_front/index.yml b/Diretorias/Diretoria Projetos/deploy/self_hosting_front/index.yml deleted file mode 100644 index 13d559c4..00000000 --- a/Diretorias/Diretoria Projetos/deploy/self_hosting_front/index.yml +++ /dev/null @@ -1,5 +0,0 @@ -icon: rocket -label: Self-Hosting (Front-End) - -# Ultima atualização: 23/09/2023 -# Autor(es): Artur Padovesi \ No newline at end of file diff --git a/Diretorias/Diretoria Projetos/deploy/heroku/como_usar.md b/Diretorias/Diretoria Projetos/deploy/servicos/heroku/como_usar.md similarity index 79% rename from Diretorias/Diretoria Projetos/deploy/heroku/como_usar.md rename to Diretorias/Diretoria Projetos/deploy/servicos/heroku/como_usar.md index 514e2ebb..ccab72f5 100644 --- a/Diretorias/Diretoria Projetos/deploy/heroku/como_usar.md +++ b/Diretorias/Diretoria Projetos/deploy/servicos/heroku/como_usar.md @@ -1,7 +1,7 @@ --- order: 1 -icon: rocket -label: "Como usar Heroku ?" +icon: plug +label: "Fazendo deploy (Rails | assets estáticos)" --- @@ -16,8 +16,8 @@ Esse deploy esta sendo feito com base em um projeto Rails 1. Crie uma branch chamada `heroku`, caso ainda não tenha, e faça as seguintes mudanças; 2. Crie um arquivo chamado `start.sh` na raíz do projeto com o seguinte conteúdo: -``` Terminal Shell -!/bin/sh +```bash +#!/bin/sh rails db:migrate bundle exec puma -C config/puma.rb ``` @@ -28,7 +28,13 @@ bundle exec puma -C config/puma.rb - `bundle exec puma -C config/puma.rb`: esse código funciona como um rails s, ou seja, serve para executar o puma (servidor padrão do rails) com alguns recursos a mais que o rails s por si só, não oferece. -3. Caso seu projeto utilize Active Storage, ou guarda alguma imagem enviada por upload, é necessário mudar o path, no qual os arquivos ficam armazenados, escolhendo entre [cloudinary](https://cloudinary.com/documentation/ruby_rails_quickstart) e [amazon s3](https://devcenter.heroku.com/articles/active-storage-on-heroku). Execute o comando **Certo** para configurar os arquivos. +!!!danger Caso seu projeto tenha banco de dados +É necessário ter uma instância separada de banco de dados. Se não me engano, o Heroku possui memória volátil, ou seja, alterações e criações de arquivos após o deploy podem ser perdidas. +!!! + +!!!danger Caso seu projeto utilize Active Storage +Ou guarde alguma imagem enviada por upload, é necessário mudar o path no qual os arquivos ficam armazenados, escolhendo entre [cloudinary](https://cloudinary.com/documentation/ruby_rails_quickstart) e [amazon s3](https://devcenter.heroku.com/articles/active-storage-on-heroku). Execute o comando **Certo** para configurar os arquivos. +!!! !!! Não colocar as chaves de acesso no repositório, apenas no heroku. Na branch de produção, requisitar as variáveis de ambiente no heroku, e colocar no código com `ENV['NOME_DA_VARIAVEL']`. @@ -59,6 +65,7 @@ bundle ## Executando deploy do projeto ### Por CLI + !!! Tutorial para instalar o CLI do heroku https://devcenter.heroku.com/articles/heroku-cli#download-and-install !!! @@ -71,7 +78,7 @@ heroku git:remote -a {nome_da_aplicação} ``` 3. Configure o banco de dados para PostgreSQL; -4. E por fim execute o comando: +4. E por fim execute o comando: ```bash Terminal git push heroku {nome_da_aplicação} @@ -84,13 +91,12 @@ git push heroku {nome_da_aplicação} 3. Navegue até a aba Deploy e selecione a opção GitHub; 4. Selecione o repositório do projeto; 5. Selecione a branch `Heroku`; -6. Selecione a opção **Deploy Branch**. +6. Selecione a opção **Deploy Branch**. ### Deploy front-end com heroku É possível usar do Heroku para fazer deploy de front-end. Basta criar um único endpoint para enviar os assets estáticos do front. Exemplo: - ```js // /package.json @@ -110,17 +116,18 @@ git push heroku {nome_da_aplicação} const express = require("express"); //chamamos o express para o arquivo -const { resolve } = require('path') +const { resolve } = require("path"); //para garantir que pegaremos o path exato const app = express(); //criamos uma aplicação com o express -app.use("/", +app.use( + "*", express.static( resolve( __dirname, - './build' // Onde os assets estáticos do front-end estão depois de rodar yarn build + "./build" // Onde os assets estáticos do front-end estão depois de rodar build ) ) ); diff --git a/Diretorias/Diretoria Projetos/deploy/servicos/heroku/explicacao.md b/Diretorias/Diretoria Projetos/deploy/servicos/heroku/explicacao.md new file mode 100644 index 00000000..a3863602 --- /dev/null +++ b/Diretorias/Diretoria Projetos/deploy/servicos/heroku/explicacao.md @@ -0,0 +1,16 @@ +--- +order: 3 +icon: question +label: "O que é?" +--- + + + + +Heroku é uma **plataforma** de deployment de website, desenvolvidos em quase todos frameworks mais famosos utimamente, ela **automaticamente** analisa o repositório e verifica a **linguagem** que você está **utilizando**, e já **faz o setup completo**, facilitando uma das principais e mais demoradas atividades de um projeto de website. + +O Heroku **roda** um **container docker** com seus **scripts** de inicialização. Isso significa que é **necessário** que o seu **projeto seja** um **servidor**, **ou seja**, que ele tenha uma porta para ser acessado, e que ele seja **capaz de responder a requisições**. Sendo assim, é ideal para api's, mas não para servir _assets estáticos_ (como os gerados numa aplicação React comum). + +!!! +O Heroku, na ultima atualização dessa documentação, não possui plano gratuito, logo utilizamos self-hosting para o back-end na Struct. +!!! diff --git a/Diretorias/Diretoria Projetos/deploy/heroku/index.yml b/Diretorias/Diretoria Projetos/deploy/servicos/heroku/index.yml similarity index 72% rename from Diretorias/Diretoria Projetos/deploy/heroku/index.yml rename to Diretorias/Diretoria Projetos/deploy/servicos/heroku/index.yml index c1bfb6dc..6b16dc3f 100644 --- a/Diretorias/Diretoria Projetos/deploy/heroku/index.yml +++ b/Diretorias/Diretoria Projetos/deploy/servicos/heroku/index.yml @@ -1,4 +1,4 @@ -icon: rocket +icon: Imagens DocStruct/Logos/heroku.svg label: Heroku # Ultima atualização: 22/09/2023 diff --git a/Diretorias/Diretoria Projetos/deploy/servicos/index.yml b/Diretorias/Diretoria Projetos/deploy/servicos/index.yml new file mode 100644 index 00000000..b7aeb3f3 --- /dev/null +++ b/Diretorias/Diretoria Projetos/deploy/servicos/index.yml @@ -0,0 +1 @@ +icon: apps diff --git a/Diretorias/Diretoria Projetos/deploy/netlify/como_usar.md b/Diretorias/Diretoria Projetos/deploy/servicos/netlify/como_usar.md similarity index 70% rename from Diretorias/Diretoria Projetos/deploy/netlify/como_usar.md rename to Diretorias/Diretoria Projetos/deploy/servicos/netlify/como_usar.md index e374e053..637f428f 100644 --- a/Diretorias/Diretoria Projetos/deploy/netlify/como_usar.md +++ b/Diretorias/Diretoria Projetos/deploy/servicos/netlify/como_usar.md @@ -1,16 +1,20 @@ --- order: 1 -icon: rocket -label: "Como usar Netlify ?" +icon: plug +label: "Fazendo deploy de assets estáticos (talvez mais?)" --- +!!! +**Só foi testado** o deploy de assets estáticos gerados por build de apps **React**. Provavelmente é **possível** hospedar uma **API**, porém **sem o Banco de Dados**. Isso porque o armazenamento do Netlify é "volátil" (não garante permanência de alterações pós deploy, pode resetar pro estado inicial a qualquer momento) +!!! + ## Configurando o projeto -1. Na própria main, mude o `/public/favicon.ico` para o real ícone do projeto. -2. Mude o `index.html`, trocando os conteúdos das tags ``, `