{"id":21096691,"url":"https://github.com/pedrohvfernandes/learn-to-use-docker","last_synced_at":"2026-04-12T06:32:20.873Z","repository":{"id":233433061,"uuid":"786955630","full_name":"PedrohvFernandes/learn-to-use-docker","owner":"PedrohvFernandes","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-17T00:35:25.000Z","size":1760,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-29T00:29:23.387Z","etag":null,"topics":["actions","build","docker","error-handling","fakerjs","fastify","nodejs","pagination","postgresql","swagger","swagger-ui","terraform","terraform-project","tsup","typescript","zod"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PedrohvFernandes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-15T16:06:18.000Z","updated_at":"2024-05-01T01:18:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"f25d1fa4-9b4a-4aea-a935-1bff3fd35eea","html_url":"https://github.com/PedrohvFernandes/learn-to-use-docker","commit_stats":null,"previous_names":["pedrohvfernandes/learn-to-use-docker"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PedrohvFernandes/learn-to-use-docker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedrohvFernandes%2Flearn-to-use-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedrohvFernandes%2Flearn-to-use-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedrohvFernandes%2Flearn-to-use-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedrohvFernandes%2Flearn-to-use-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PedrohvFernandes","download_url":"https://codeload.github.com/PedrohvFernandes/learn-to-use-docker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedrohvFernandes%2Flearn-to-use-docker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31706764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-12T06:22:27.080Z","status":"ssl_error","status_checked_at":"2026-04-12T06:21:52.710Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","build","docker","error-handling","fakerjs","fastify","nodejs","pagination","postgresql","swagger","swagger-ui","terraform","terraform-project","tsup","typescript","zod"],"created_at":"2024-11-19T22:39:09.992Z","updated_at":"2026-04-12T06:32:20.858Z","avatar_url":"https://github.com/PedrohvFernandes.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pass.in\n\nO pass.in é uma aplicação de **gestão de participantes em eventos presenciais**. \n\nA ferramenta permite que o organizador cadastre um evento e abra uma página pública de inscrição.\n\nOs participantes inscritos podem emitir uma credencial para check-in no dia do evento.\n\nO sistema fará um scan da credencial do participante para permitir a entrada no evento.\n\n## Requisitos\n\n### Requisitos funcionais\n\n- [x] O organizador deve poder cadastrar um novo evento;\n- [x] O organizador deve poder visualizar dados de um evento;\n- [x] O organizador deve poder visualizar a lista de participantes; \n- [x] O participante deve poder se inscrever em um evento;\n- [x] O participante deve poder visualizar seu crachá de inscrição;\n- [x] O participante deve poder realizar check-in no evento;\n\n### Regras de negócio\n\n- [x] O participante só pode se inscrever em um evento uma única vez;\n- [x] O participante só pode se inscrever em eventos com vagas disponíveis;\n- [x] O participante só pode realizar check-in em um evento uma única vez;\n\n### Requisitos não-funcionais\n\n- [x] O check-in no evento será realizado através de um QRCode;\n\n## Documentação da API (Swagger)\n\nPara documentação da API, acesse o link: https://nlw-unite-nodejs.onrender.com/docs\n\n## Banco de dados\n\nNessa aplicação vamos utilizar banco de dados relacional (SQL). Para ambiente de desenvolvimento seguiremos com o SQLite pela facilidade do ambiente.\n\n### Diagrama ERD\n\n\u003cimg src=\".github/erd.svg\" width=\"600\" alt=\"Diagrama ERD do banco de dados\" /\u003e\n\n### Estrutura do banco (SQL)\n\n```sql\n-- CreateTable\nCREATE TABLE \"events\" (\n    \"id\" TEXT NOT NULL PRIMARY KEY,\n    \"title\" TEXT NOT NULL,\n    \"details\" TEXT,\n    \"slug\" TEXT NOT NULL,\n    \"maximum_attendees\" INTEGER\n);\n\n-- CreateTable\nCREATE TABLE \"attendees\" (\n    \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n    \"name\" TEXT NOT NULL,\n    \"email\" TEXT NOT NULL,\n    \"event_id\" TEXT NOT NULL,\n    \"created_at\" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    CONSTRAINT \"attendees_event_id_fkey\" FOREIGN KEY (\"event_id\") REFERENCES \"events\" (\"id\") ON DELETE RESTRICT ON UPDATE CASCADE\n);\n\n-- CreateTable\nCREATE TABLE \"check_ins\" (\n    \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n    \"created_at\" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    \"attendeeId\" INTEGER NOT NULL,\n    CONSTRAINT \"check_ins_attendeeId_fkey\" FOREIGN KEY (\"attendeeId\") REFERENCES \"attendees\" (\"id\") ON DELETE RESTRICT ON UPDATE CASCADE\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"events_slug_key\" ON \"events\"(\"slug\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"attendees_event_id_email_key\" ON \"attendees\"(\"event_id\", \"email\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"check_ins_attendeeId_key\" ON \"check_ins\"(\"attendeeId\");\n```\n### Comando para criar o ORM prisma em Sqlite\n```bash\nnpx prisma init --datasource-provider SQLite\n\nnpx prisma migrate dev \n# ou\nnpm run db:migrate\n\nnpx prisma studio\n# ou\nnpm run db:studio\n\n# Para gerar o prisma client apos a instalar a dependência do prisma\nnpx prisma generate\n# ou\nnpm run db:generate\n```\n\n### Comando do node para ler .env(Variaveis de ambiente)\n```bash\n# Maneira tradicional: Instalar a dependência dotenv\nnpm install dotenv\n\n# ou\n\n# No package.json, passar --env-file .env na execução do script. O proprio node suporta a leitura do .env. E pelo fato de estarmos usando o tsx ele ja passa o arquivo .env para o node automaticamente: node --env-file .env src/server.js\n  \"scripts\": {\n    \"dev\": \"tsx watch --env-file .env src/server.ts\"\n  }\n```\n\n### Anotações:\n\n- Métodos HTTP para fins semanticos: GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD\n  -  Get - Obter dados\n  -  Post - Criar dados...\n\n- Maneiras de passar parametros para o servidor:\n  - Query/search params: site.../users?name=Lucas\u0026age=25 --\u003e Parametros passados na URL --\u003e Parametros de busca/filtro --\u003e Esses parametros não são obrigatórios --\u003e Podem ser usados para filtrar os resultados de uma busca\n\n  - Route params: /users/10 (id do usuario) --\u003e site.../users/:id --\u003e site.../users/5 --\u003e Parametros de rota passados na URL --\u003e Identificação de recursos --\u003e Para Put, Delete, Patch ou ate get--\u003e fazer uma operação em um unico registro --\u003e Por exemplo para deletar um usuario --\u003e Esses parametros são obrigatórios\n\n  - Body: { name: 'Lucas', age: 25 } --\u003e Corpo da requisição\n\n  - Headers: { Authorization : 'Bearer 123456' } --\u003e Cabeçalhos --\u003e Contexto da requisição --\u003e Informações mais fixas, para detalhar a requisição/back-end --\u003e Ex: a localização do usuario, o tipo de conteudo que ele aceita, o tipo de conteudo que ele envia, a autenticação do usuario\n\n- Maneiras de conectar com o banco:\n  -  Driver nativo: Conexão direta(Baixo nivel) com o banco de dados --\u003e Ex: mysql, pg, sqlite --\u003e Necessita de conhecimento avançado em SQL\n  -  ORM: Object Relational Mapping --\u003e Mapeamento de objetos para o banco de dados --\u003e Ex: TypeORM, Sequelize, Prisma, Hibernate(Para Java)...\n  -  Query Builder: Construção de queries SQL com métodos/sintaxe Javascript --\u003e Knex.js...\n\n  -  Migrations --\u003e Controle de versão do banco de dados --\u003e Criação de tabelas, alteração de tabelas, exclusão de tabelas...\n\n- Http status code: Traz o significado da resposta\n  -  2xx: Sucesso\n  -  3xx: Redirecionamento\n  -  4xx: Erro do cliente(Erro em alguma informação enviada por QUEM esta fazendo a chamada p/ API)\n  -  5xx: Erro do servidor(Um erro que está acontecendo IDEPENDENTE do que está sendo enviado p/ o servidor)\n\n- Caso queira gerar regex de maneira facil, basta usar o Chatgpt:\n  -  Me dê uma função em typescript que gere um slug a partir de um texto sem acentos, símbolos ou espaços, ou seja, pronto para ser usado em uma URL\n  ```bash\n      export function generateSlug(text: string): string {\n      return text\n        .normalize('NFD')\n        .replace(/[\\u0300-\\u036f]/g, '')\n        .toLowerCase()\n        .replace(/[^\\w\\s-]/g, '')\n        .replace(/\\s+/g, '-')\n    }\n  ```\n- Arquivo para pre-popular nosso BD, o arquivo *seed* em prisma\n- Em package.json:\n```bash\n  \"prisma\": {\n    \"seed\": \"tsx prisma/seed.ts\"\n  }\n```\ndepois rode o comando para popular o banco:\n```bash\n  npx prisma db seed\n```\n- Documentação da Api usando o Swagger: https://swagger.io/ e iremos usar o fastify junto com ele para gerar o arquivo de documentação yml ou json da API *fastify/swagger*, o *fastify/swagger-ui* cria a interface para visualizar/navegar pela documentação da API\n```bash \n  npm i @fastify/swagger @fastify/swagger-ui\n```\n- Para abrir e testar a documentação da API, basta acessar a rota /docs: http://localhost:3000/docs\n- Fazendo o build para subir a aplicação para produção\n```bash\n  npm i tsup -D\n```\n- Script de build para preparar nossa aplicação para produção\n```bash\n  \"scripts\": {\n    # Para gerar o build no formato ESM (EcmaScript Module) de exportação e importação diretamente das funções, classes, variáveis, arquivos...\n    \"build:esm\": \"tsup src --format esm\",\n    # Para gerar o build no formato CommonJS padrão antigo de exportação e importação, module export\n    \"build:cjs\": \"tsup src --format cjs\",\n  }\n```\n- Para rodar o build: `npm run start`, ou seja, a plicação em JS\n```bash\n  \"scripts\": {\n    \"start\": \"node dist/server.mjs\"\n  }\n```\n- Devops\n  - O docker hub nada mais é que um repositorio de imagens docker, onde podemos subir nossas imagens para serem usadas em qualquer lugar\n  - [Imagens Docker](https://hub.docker.com/)\n  - [Imagens Docker node](https://hub.docker.com/_/node)\n  - [Imagem docker node 20](https://hub.docker.com/_/node/tags?page=\u0026page_size=\u0026ordering=\u0026name=20)\n  - [Imagem docker node 20-alpine3.19](https://hub.docker.com/_/node/tags?page=\u0026page_size=\u0026ordering=\u0026name=20-alpine3.19)\n  - [Para baixar o docker no windows](https://docs.docker.com/desktop/windows/install/)\n  - [Lembre de ter o WSL2 instalado](https://docs.microsoft.com/pt-br/windows/wsl/install)\n  - [Como instalar o WSL2 no Windows 10/11 - Linux e Windows Lado a Lado para Iniciantes](https://www.youtube.com/watch?v=qlLcnSvG1rA)\n  - Após instalar tudo basta iniciar, que qualquer comando via CLI do windows será executado\n  - Para baixar a imagem do docker do node da tag 20 na maquina(servidor/pc): ```docker pull node:20``` pode demorar um pouco\n    - Retorno após baixar a imagem:\n      ```bash\n        0: Pulling from library/node\n        71215d55680c: Pull complete\n        3cb8f9c23302: Pull complete\n        5f899db30843: Pull complete\n        567db630df8d: Pull complete\n        f4ac4e9f5ffb: Pull complete\n        eecc94e1c146: Pull complete\n        5bbcc6307f26: Pull complete\n        18e47472a9da: Pull complete\n        Digest: sha256:8a03de2385cb16c4d76aac30bf86ab05f55f1754a5402dc9039916e8043f019a\n        Status: Downloaded newer image for node:20\n        docker.io/library/node:20\n      ```\n    - Rode um ```docker image ls``` para ver as imagens baixadas no seu sistema\n      - Retorno do meu:\n        ```bash\n            REPOSITORY           TAG       IMAGE ID       CREATED        SIZE\n            node                 20        8e022d47db62   4 days ago     1.1GB\n            bitnami/postgresql   latest    9b84f4e4d643   2 months ago   274MB\n            bitnami/redis        latest    45de196aef7e   2 months ago   95.2MB\n        ```\n  - Para baixar a imagem do docker do node da tag 20-alpine3.19: ```docker pull node:20-alpine3.19``` pode demorar um pouco, so que menos, porque ela é 135MB, esse minimo ja da para rodar o node\n    - Retorno após baixar a imagem:\n      ```bash\n          20-alpine3.19: Pulling from library/node\n          4abcf2066143: Pull complete\n          77152dc4dbd8: Pull complete\n          f90945061f81: Pull complete\n          c95f6f65e1db: Pull complete\n          Digest: sha256:7e227295e96f5b00aa79555ae166f50610940d888fc2e321cf36304cbd17d7d6\n          Status: Downloaded newer image for node:20-alpine3.19\n          docker.io/library/node:20-alpine3.19\n      ```\n    - Rode um ```docker image ls``` para ver as imagens baixadas no seu sistema\n      - Retorno do meu:\n        ```bash\n            REPOSITORY           TAG             IMAGE ID       CREATED        SIZE\n            node                 20              8e022d47db62   4 days ago     1.1GB\n            node                 20-alpine3.19   bc27e8ab8b21   4 days ago     135MB\n            bitnami/postgresql   latest          9b84f4e4d643   2 months ago   274MB\n            bitnami/redis        latest          45de196aef7e   2 months ago   95.2MB\n        ```\n  - Para rodar a imagem feita por a gente, basta ir no direitorio onde tem o arquivo Dockerfile e rodar o comando ```docker build -t nome_da_imagem:v1 .``` o ponto no final é para dizer que o arquivo Dockerfile está no diretorio atual, os : é para dizer a tag da imagem, o -t é para dar um nome a imagem\n    - Exemplo: ```docker build -t passin:v1 .```\n    - Exemplo caso você não esteja no terminal aberto com o direitorio da sua aplicação com o dockerfile(vscode basta abrir um terminal de acordo com a pasta) e queira passar o endereço da sua aplicação com o Dockerfile em outro terminal aberto em outro diretorio: ```docker build -t passin:v1 -f /caminho/para/o/Dockerfile .```\n    - Resultado:\n    ```bash\n        docker build -t passin:v1 .\n    [+] Building 21.1s (15/21)                                                                                                          docker:default\n    =\u003e [internal] load build definition from Dockerfile                                                                                          0.1s\n    =\u003e =\u003e transferring dockerfile: 5.12kB                                                                                                        0.0s\n    =\u003e [internal] load metadata for docker.io/library/node:20                                                                                    0.0s\n    =\u003e [internal] load metadata for docker.io/library/node:20-alpine3.19                                                                         0.0s\n    =\u003e [internal] load .dockerignore                                                                                                             0.0s\n    =\u003e =\u003e transferring context: 153B                                                                                                             0.0s\n    =\u003e [deploy 1/8] FROM docker.io/library/node:20-alpine3.19                                                                                    0.1s\n    =\u003e [internal] load build context                                                                                                             0.1s\n    =\u003e =\u003e transferring context: 341.52kB                                                                                                         0.0s\n    =\u003e [base 1/1] FROM docker.io/library/node:20                                                                                                 0.2s\n    =\u003e [deploy 2/8] WORKDIR /usr/src/app                                                                                                         0.1s\n    =\u003e [deploy 3/8] RUN npm i -g prisma                                                                                                         10.7s \n    =\u003e [dependencies 1/3] WORKDIR /usr/src/app                                                                                                   0.0s \n    =\u003e [dependencies 2/3] COPY package.json package-lock.json ./                                                                                 0.0s \n    =\u003e [build 2/5] COPY . .                                                                                                                      0.1s \n    =\u003e [dependencies 3/3] RUN npm install                                                                                                        16.8s \n    =\u003e [build 3/5] COPY --from=dependencies /usr/src/app/node_modules ./node_modules                                                             2.2s\n    =\u003e [build 4/5] RUN npm run build:esm                                                                                                         1.2s \n    =\u003e [build 5/5] RUN npm prune --prod                                                                                                          2.1s \n    =\u003e [deploy 4/8] COPY --from=build /usr/src/app/dist ./dist                                                                                   0.0s \n    =\u003e [deploy 5/8] COPY --from=build /usr/src/app/node_modules ./node_modules                                                                   1.2s \n    =\u003e [deploy 6/8] COPY --from=build /usr/src/app/package.json ./package.json                                                                   0.0s \n    =\u003e [deploy 7/8] COPY --from=build /usr/src/app/prisma ./prisma                                                                               0.0s \n    =\u003e [deploy 8/8] RUN npx prisma generate                                                                                                      2.1s \n    =\u003e exporting to image                                                                                                                        0.9s \n    =\u003e =\u003e exporting layers                                                                                                                       0.9s \n    =\u003e =\u003e writing image sha256:5d01caa891d2896bf3e1c6a9818af954bc935ebd5d317163bf93292ffd138f4b                                                  0.0s \n    =\u003e =\u003e naming to docker.io/library/passin:v1                                                                                                  0.0s \n\n    What's Next?\n      View a summary of image vulnerabilities and recommendations → docker scout quickview \n    ```\n  - Rodando um ```docker image ls```\n    - Resultado:\n      ```bash\n      PS C:\\Users\\Pedro\\OneDrive\\Documentos\\GitHub\\nlw-unite\\api\u003e docker image ls\n      REPOSITORY           TAG             IMAGE ID       CREATED         SIZE\n      passin               v1              5d01caa891d2   5 minutes ago   587MB\n      node                 20              8e022d47db62   9 days ago      1.1GB\n      node                 20-alpine3.19   bc27e8ab8b21   9 days ago      135MB\n      bitnami/postgresql   latest          9b84f4e4d643   2 months ago    274MB\n      bitnami/redis        latest          45de196aef7e   2 months ago    95.2MB\n      \n      ```\n  - Rodando o docker ```docker run -p 3001:3000 passin:v1```\n    - Resultado\n      ``` bash\n      docker run -p 3001:3000 passin:v1\n\n      \u003e api@1.0.0 start\n      \u003e node dist/server.mjs\n\n      Server is running on \n      ```\n    - definimos a porta do docker com a flag -p, a primeira porta é a porta do docker e a segunda é a porta da nossa aplicação\n  - Não havíamos passado as variáveis de ambiente para o docker, logo pode dar algum erro, para solucionar basta passar via arquivo dotenv. Não criamos o dotenv para o docker que seria o ideal, passamos as variaveis de ambiente para o docker diretamente no arquivo dockerfile. \n  - Apos isso, de um ```docker build -t passin:v2 .``` para atualizar a imagem do docker e depois rode o ```docker run -p 3001:3000 passin:v2``` para rodar a nova imagem\n    - Resultado apos colocar as variaveis\n      ```bash\n      docker run -p 3001:3000 passin:v2\n\n      \u003e api@1.0.0 start\n      \u003e node dist/server.mjs\n\n      Server is running on http://localhost:3000\n      ```\n  - Lembrando que o localhost:3000 é dentro do docker, para nós a porta é 3001 porque usamos o docker para subir a aplicação, usando a porta 3001 para subir a imagem do mesmo, logo se eu quiser acessar agora documentação da minha api não é mais http://localhost:3000/docs e sim http://localhost:3001/docs que foi a porta que definimos ao subir a imagem. Se eu der um ctrl+C a aplicação finaliza, para isso não ocorrer, para não depender desse terminal para rodar a imagem, basta rodar a imagem de outra maneira:\n      - ```docker run -p 3001:3000 -d passin:v2``` o -d é para fazer a execução e não travar o meu terminal, dessa forma nossa imagem roda como qualquer outra imagem de terceiros que usamos para rodar em outras aplicações(ex: bd redis, postgress) na nossa maquina usando o docker, ou seja, ficam de fundo rondando, para ver quais imagens estão executando: ```docker ps```, para parar basta ir na UI do Docker e parar ou via CLI ```docker stop CONTAINER ID```\n       - Resultado da execução docker run -p 3001:3000 -d passin:v2: *0059444199ecebe25e39a72a7b7209944ac6478a29a1c6ae5b34da95c253516d*\n       - Resultado da execução pra ver quais imagens estão rodando:\n         ```bash\n         docker ps\n         CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                    NAMES\n         0059444199ec   passin:v2   \"docker-entrypoint.s…\"   57 seconds ago   Up 56 seconds   0.0.0.0:3001-\u003e3000/tcp   strange_heyrovsky\n         ```\n         - Aqui vemos que a porta 3001(da nossa imagem) aponta para a porta da nossa aplicação 3000 --\u003e 0.0.0.0:3001-\u003e3000/tcp\n  - Dockers passados ```docker ps -a```\n    ```bash\n      CONTAINER ID   IMAGE                       COMMAND                  CREATED          STATUS                      PORTS                    NAMES\n      0059444199ec   passin:v2                   \"docker-entrypoint.s…\"   3 minutes ago    Up 3 minutes                0.0.0.0:3001-\u003e3000/tcp   strange_heyrovsky\n      148dcfddf162   passin:v2                   \"docker-entrypoint.s…\"   13 minutes ago   Exited (1) 4 minutes ago                             quizzical_chaum\n      bf0ceb014b01   passin:v1                   \"docker-entrypoint.s…\"   20 minutes ago   Exited (1) 13 minutes ago                            exciting_sammet\n      c24c2f06be99   passin:v1                   \"docker-entrypoint.s…\"   21 minutes ago   Exited (1) 20 minutes ago                            zen_hellman\n      4bd857564eb1   bitnami/postgresql:latest   \"/opt/bitnami/script…\"   3 weeks ago      Exited (0) 3 weeks ago                               url-shortening-system-with-node-postgres-1\n      3ef72e5abce5   bitnami/redis:latest        \"/opt/bitnami/script…\"   3 weeks ago      Exited (0) 3 weeks ago                               url-shortening-system-with-node-redis-1\n      240a81c65fc1   bitnami/redis:latest        \"/opt/bitnami/script…\"   2 months ago     Exited (0) 8 weeks ago                               trilha-node-polls-redis-1\n      9c7975954ade   bitnami/postgresql:latest   \"/opt/bitnami/script…\"   2 months ago     Exited (0) 8 weeks ago                               trilha-node-polls-postgres-1\n    ``` \n  - Logs ```docker logs CONTAINER ID```\n  - Temos o docker compose, para instalar e rodar imagens de terceiros ou a nossa mesma(dockerfile), nesse caso iremos usar o postgress e a nossa imagem(dockerfile). Para saber se esta instalado basta dar um ```docker-compose -v```\n    - Resultado: *Docker Compose version v2.24.3-desktop.1*\n  - O docker compose é uma ferramenta somente para ambiente local, servindo para orquestração de containers. Ou seja, conseguimos ter dois serviços rodando ou mais e fazendo a execução com apenas um comendo na mesma camada de rede, no mesmo container, conseguindo associar volume... Para que consigamos instalar e rodar imagens de terceiros ou a nossa propria imagem(Dockerfile) em um so container(onde cada serviço é um container e cada serviço tem a sua imagem) com um so comando, criamos o docker-compose.yml, onde passamos os serviços que queremos rodar\n  - Tiramos as envs do dockerfile e passamos para o docker-compose\n  - E agora invés do ```docker build``` passando uma nova tag de uma nova versão, rodamos o ```docker-compose up --build -d``` para buildar e subir a imagem para criar o container ou ```docker-compose up -d``` somente para subir a imagem para criar o container. o -d é mesma logica do docker run, para o console/terminal não ficar travado. Para encerrar via CLI ```docker-compose down``` ou via UI. Se quiser subir de novo sem precisar buildar novamente ```docker-compose up -d```\n    - Resultado:\n      ```bash\n          docker-compose up --build -d\n          [+] Building 0.0s (0/0)  docker:default\n          [+] Building 10.4s (22/22) FINISHED                                                                                                 docker:default\n          =\u003e [api-pass-in internal] load build definition from Dockerfile                                                                              0.0s\n          =\u003e =\u003e transferring dockerfile: 5.48kB                                                                                                        0.0s \n          =\u003e [api-pass-in internal] load metadata for docker.io/library/node:20                                                                        0.0s \n          =\u003e [api-pass-in internal] load metadata for docker.io/library/node:20-alpine3.19                                                             0.0s \n          =\u003e [api-pass-in internal] load .dockerignore                                                                                                 0.0s \n          =\u003e =\u003e transferring context: 153B                                                                                                             0.0s \n          =\u003e [api-pass-in base 1/1] FROM docker.io/library/node:20                                                                                     0.0s \n          =\u003e [api-pass-in internal] load build context                                                                                                 0.0s \n          =\u003e =\u003e transferring context: 2.98kB                                                                                                           0.0s \n          =\u003e [api-pass-in deploy 1/8] FROM docker.io/library/node:20-alpine3.19                                                                        0.0s \n          =\u003e CACHED [api-pass-in dependencies 1/3] WORKDIR /usr/src/app                                                                                0.0s\n          =\u003e CACHED [api-pass-in dependencies 2/3] COPY package.json package-lock.json ./                                                              0.0s \n          =\u003e CACHED [api-pass-in dependencies 3/3] RUN npm install                                                                                     0.0s \n          =\u003e [api-pass-in build 2/5] COPY . .                                                                                                          0.0s \n          =\u003e [api-pass-in build 3/5] COPY --from=dependencies /usr/src/app/node_modules ./node_modules                                                 5.7s \n          =\u003e [api-pass-in build 4/5] RUN npm run build:esm                                                                                             1.3s \n          =\u003e [api-pass-in build 5/5] RUN npm prune --prod                                                                                              2.2s \n          =\u003e CACHED [api-pass-in deploy 2/8] WORKDIR /usr/src/app                                                                                      0.0s \n          =\u003e CACHED [api-pass-in deploy 3/8] RUN npm i -g prisma                                                                                       0.0s \n          =\u003e CACHED [api-pass-in deploy 4/8] COPY --from=build /usr/src/app/dist ./dist                                                                0.0s \n          =\u003e CACHED [api-pass-in deploy 5/8] COPY --from=build /usr/src/app/node_modules ./node_modules                                                0.0s \n          =\u003e CACHED [api-pass-in deploy 6/8] COPY --from=build /usr/src/app/package.json ./package.json                                                0.0s \n          =\u003e CACHED [api-pass-in deploy 7/8] COPY --from=build /usr/src/app/prisma ./prisma                                                            0.0s \n          =\u003e CACHED [api-pass-in deploy 8/8] RUN npx prisma generate                                                                                   0.0s \n          =\u003e [api-pass-in] exporting to image                                                                                                          0.0s \n          =\u003e =\u003e exporting layers                                                                                                                       0.0s \n          =\u003e =\u003e writing image sha256:7aa827dc2070f3582a67da33d174d84901c01584e54319be76c4937e24dfe583                                                  0.0s \n          =\u003e =\u003e naming to docker.io/library/api-api-pass-in                                                                                            0.0s \n          [+] Running 0/2\n          - Network api_default    Created                                                                                                             0.3s \n          - Container api_pass_in  Starting                                                                                                            0.3s \n          Error response from daemon: driver failed programming external connectivity on endpoint api_pass_in (45318b57010c9a20d82a54cf095761d894decddb0f7d6636289352ed5e4a5ba8): Bind for 0.0.0.0:3001 failed: port is already allocated\n      ```\n    - Ele deu um erro *Error response from daemon: driver failed programming external connectivity on endpoint api_pass_in (45318b57010c9a20d82a54cf095761d894decddb0f7d6636289352ed5e4a5ba8): Bind for 0.0.0.0:3001 failed: port is already allocated* Porque ja estamos utilizando a porta 3001, basta fazer isso ```docker ps``` pegar o container que esta rodando nessa porta e dar um ```docker stop CONTAINER ID```\n      - Docker ps:\n        ```bash\n          CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                    NAMES\n          0059444199ec   passin:v2   \"docker-entrypoint.s…\"   32 minutes ago   Up 32 minutes   0.0.0.0:3001-\u003e3000/tcp   strange_heyrovsky\n        ```\n      - docker stop 0059444199ec. Agora podemos rodar o up\n        - docker up...\n          ```bash\n          2024/04/13 15:19:34 http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed\n          [+] Building 0.0s (0/0)  docker:default\n          [+] Building 0.1s (22/22) FINISHED                                                                                                  docker:default\n          =\u003e [api-pass-in internal] load build definition from Dockerfile                                                                              0.0s\n          =\u003e =\u003e transferring dockerfile: 5.48kB                                                                                                        0.0s \n          =\u003e [api-pass-in internal] load metadata for docker.io/library/node:20-alpine3.19                                                             0.0s \n          =\u003e [api-pass-in internal] load metadata for docker.io/library/node:20                                                                        0.0s \n          =\u003e [api-pass-in internal] load .dockerignore                                                                                                 0.0s \n          =\u003e =\u003e transferring context: 153B                                                                                                             0.0s \n          =\u003e [api-pass-in base 1/1] FROM docker.io/library/node:20                                                                                     0.0s \n          =\u003e [api-pass-in deploy 1/8] FROM docker.io/library/node:20-alpine3.19                                                                        0.0s \n          =\u003e [api-pass-in internal] load build context                                                                                                 0.0s \n          =\u003e =\u003e transferring context: 2.17kB                                                                                                           0.0s \n          =\u003e CACHED [api-pass-in deploy 2/8] WORKDIR /usr/src/app                                                                                      0.0s \n          =\u003e CACHED [api-pass-in deploy 3/8] RUN npm i -g prisma                                                                                       0.0s \n          =\u003e CACHED [api-pass-in dependencies 1/3] WORKDIR /usr/src/app                                                                                0.0s \n          =\u003e CACHED [api-pass-in build 2/5] COPY . .                                                                                                   0.0s \n          =\u003e CACHED [api-pass-in dependencies 2/3] COPY package.json package-lock.json ./                                                              0.0s \n          =\u003e CACHED [api-pass-in dependencies 3/3] RUN npm install                                                                                     0.0s \n          =\u003e CACHED [api-pass-in build 3/5] COPY --from=dependencies /usr/src/app/node_modules ./node_modules                                          0.0s \n          =\u003e CACHED [api-pass-in build 4/5] RUN npm run build:esm                                                                                      0.0s \n          =\u003e CACHED [api-pass-in build 5/5] RUN npm prune --prod                                                                                       0.0s \n          =\u003e CACHED [api-pass-in deploy 4/8] COPY --from=build /usr/src/app/dist ./dist                                                                0.0s \n          =\u003e CACHED [api-pass-in deploy 5/8] COPY --from=build /usr/src/app/node_modules ./node_modules                                                0.0s \n          =\u003e CACHED [api-pass-in deploy 6/8] COPY --from=build /usr/src/app/package.json ./package.json                                                0.0s \n          =\u003e CACHED [api-pass-in deploy 7/8] COPY --from=build /usr/src/app/prisma ./prisma                                                            0.0s \n          =\u003e CACHED [api-pass-in deploy 8/8] RUN npx prisma generate                                                                                   0.0s \n          =\u003e [api-pass-in] exporting to image                                                                                                          0.0s \n          =\u003e =\u003e exporting layers                                                                                                                       0.0s \n          =\u003e =\u003e writing image sha256:7aa827dc2070f3582a67da33d174d84901c01584e54319be76c4937e24dfe583                                                  0.0s \n          =\u003e =\u003e naming to docker.io/library/api-api-pass-in                                                                                            0.0s \n          [+] Running 1/1\n          ✔ Container api_pass_in  Started     \n          ```\n  - Agora iremos preparar a aplicação para receber o postgres, removendo o arquivo dev.db que era usado pelo SQlite, depois indo no prisma configuramos para receber o postgres, depois removemos o migration_lock em migrations, depois em cada migration mudamos o *autoincrement*, porque no postgres não possui *autoincrement*, usamos o *serial* que é o equivalente ao *autoincrement* do SQlite, e o integer tambem não é necessario visto que um campo *serial* ja é um campo *integer* no postgres. Mudamos também o tipo *DATETIME* para *TIMESTAMP* \n  - Agora declaramos outro serviço dentro do docker-compose o postgres\n  - Para rodar o docker-compose com o postgres basta rodar o ```docker-compose up --build -d``` ele vai fazer baixar, fazer o pull da imagem do postgres(postgres:16.2-alpine3.19) de acordo com a tag que foi definida e o build da nossa imagem(api-api-pass-in) e subir os dois containers(api-pass-in e db-pass-in) em um pacote de container(learn-to-use-docker(nome da nossa aplicação))\n    ```bash\n        [+] Running 10/10\n        ✔ postgres 9 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                      10.9s \n          ✔ 4abcf2066143 Already exists                                                                                                                              0.0s \n          ✔ 128d1b74d24d Pull complete                                                                                                                               0.7s \n          ✔ 0a392327555d Pull complete                                                                                                                               0.6s \n          ✔ 0e14a31643e8 Pull complete                                                                                                                               5.7s \n          ✔ 904e95badb7d Pull complete                                                                                                                               1.2s \n          ✔ 8f6103a2e811 Pull complete                                                                                                                               1.4s \n          ✔ 02b106837f9f Pull complete                                                                                                                               1.8s \n          ✔ d34b010d3edc Pull complete                                                                                                                               2.0s \n          ✔ 696a345da38f Pull complete                                                                                                                               2.5s \n        [+] Building 10.2s (22/22) FINISHED                                                                                                                 docker:default\n        =\u003e [api-pass-in internal] load build definition from Dockerfile                                                                                              0.0s\n        =\u003e =\u003e transferring dockerfile: 5.48kB                                                                                                                        0.0s \n        =\u003e [api-pass-in internal] load metadata for docker.io/library/node:20-alpine3.19                                                                             0.0s \n        =\u003e [api-pass-in internal] load metadata for docker.io/library/node:20                                                                                        0.0s \n        =\u003e [api-pass-in internal] load .dockerignore                                                                                                                 0.0s \n        =\u003e =\u003e transferring context: 153B                                                                                                                             0.0s \n        =\u003e [api-pass-in base 1/1] FROM docker.io/library/node:20                                                                                                     0.0s \n        =\u003e [api-pass-in deploy 1/8] FROM docker.io/library/node:20-alpine3.19                                                                                        0.0s \n        =\u003e [api-pass-in internal] load build context                                                                                                                 0.0s \n        =\u003e =\u003e transferring context: 5.01kB                                                                                                                           0.0s\n        =\u003e CACHED [api-pass-in dependencies 1/3] WORKDIR /usr/src/app                                                                                                0.0s \n        =\u003e CACHED [api-pass-in dependencies 2/3] COPY package.json package-lock.json ./                                                                              0.0s \n        =\u003e CACHED [api-pass-in dependencies 3/3] RUN npm install                                                                                                     0.0s \n        =\u003e [api-pass-in build 2/5] COPY . .                                                                                                                          0.0s \n        =\u003e [api-pass-in build 3/5] COPY --from=dependencies /usr/src/app/node_modules ./node_modules                                                                 2.4s \n        =\u003e [api-pass-in build 4/5] RUN npm run build:esm                                                                                                             1.1s \n        =\u003e [api-pass-in build 5/5] RUN npm prune --prod                                                                                                              2.1s \n        =\u003e CACHED [api-pass-in deploy 2/8] WORKDIR /usr/src/app                                                                                                      0.0s \n        =\u003e CACHED [api-pass-in deploy 3/8] RUN npm i -g prisma                                                                                                       0.0s \n        =\u003e CACHED [api-pass-in deploy 4/8] COPY --from=build /usr/src/app/dist ./dist                                                                                0.0s \n        =\u003e CACHED [api-pass-in deploy 5/8] COPY --from=build /usr/src/app/node_modules ./node_modules                                                                0.0s \n        =\u003e CACHED [api-pass-in deploy 6/8] COPY --from=build /usr/src/app/package.json ./package.json                                                                0.0s \n        =\u003e [api-pass-in deploy 7/8] COPY --from=build /usr/src/app/prisma ./prisma                                                                                   0.0s \n        =\u003e [api-pass-in deploy 8/8] RUN npx prisma generate                                                                                                          3.5s \n        =\u003e [api-pass-in] exporting to image                                                                                                                          0.3s \n        =\u003e =\u003e exporting layers                                                                                                                                       0.3s \n        =\u003e =\u003e writing image sha256:a480c10407aafab9949edc298586b5db0c6829764f10d5a62b1f3a6d47319570                                                                  0.0s \n        =\u003e =\u003e naming to docker.io/library/api-api-pass-in                                                                                                            0.0s \n        [+] Running 2/3\n        ✔ Container db-pass-in-postgres  Started                                                                                                                     0.9s \n        - Container api_pass_in          Recreated                                                                                                                   1.2s \n        ✔ Container api-pass-in          Started                                                                                                                     0.4s\n    ```\n\n  - ```docker-compose up -d``` para subir a aplicação sem precisar buildar novamente\n  - Para ver se os containers estão rodando basta rodar o ```docker ps``` e para ver todos os containers que ja rodaram basta rodar o ```docker ps -a``` ou container que existem mas que não estão rodando e que estão rodando```docker container ls```\n  - Para ver o log dos nossos containers via CLI basta rodar o ```docker logs CONTAINER ID```, da para ver os logs via UI\n  - Rodamos sempre com build para caso tenha alguma alteração no dockerfile ou no docker-compose quando alterar algo da nossa imagem, ele ja builda a nossa imagem(Dockerfile) e sobe os containers(serviços) com as alterações(api-pass-in e db-pass-in)\n  - Para parar algum container especifico basta rodar o ```docker stop CONTAINER ID```\n  - Para remover todos os containers basta rodar o ```docker-compose down```\n  - Para remover algum container(ex: db-pass-in) especifico do nosso pacote de container(ex: learn-to-use-docker) basta rodar o ```docker rm CONTAINER ID``` lembrando que a imagem ainda vai estar la(ex:postgres:16.2-alpine3.19) no docker, ou seja, no sistema, para remover a imagem basta rodar o ```docker rmi IMAGE ID``` para ver os id das imagens basta rodar o ```docker image ls```\n  - para subir somente o container que foi interrompido  basta rodar o ```docker-compose up -d NOME_DO_SERVIÇO``` --\u003e ```docker-compose up -d postgres``` ou ```docker-compose up``` Sobe tudo que estiver  no docker-compose.yml\n  - Caso seja necessario fazer migrations no banco de dados da nossa api ao subir os containers, basta ir no comando start no *package.json* e adicionar o comando de migration no start ```npm run db:migrate-deploy \u0026\u0026 node dist/server.mjs``` e no Dockerfile deixar no CMD npm start. Não tem problema de deixar o comando da migration no start, porque se paramos algum container que não seja da api(api-pass-in) ao dar o ```docker-compose up -d``` ele vai subir somente o container que foi interrompido, mas caso interrompa o container da api e execute o npm run start ao subir o container da api e rodar as migration não sera um problema, porque o volumes do postgres não são apagados, logo as migrations não serão executadas novamente\n  - Então lembre de criar o volumes para o container do banco de dados, para que os dados não se percam quando o container do postgres for removido e quando o container da api desligar, subir e rodar a migrations novamente ao subir o container da api, para isso basta ir no docker-compose.yml e adicionar o volumes no container do Banco de dados.\n  - Depois de um ```docker-compose up --build -d``` para subir a aplicação e pegar o novo *package.json* com o comando start alterado.\n\n\n  - Iniciar:\n    - ```npm i```\n    - ```npx prisma generate```\n\n  - Como iniciar a aplicação via Dev e bd docker localmente:\n    - Sobe a nossa api normalmente ```npm run dev```\n    - Sobe o serviço do Bd via docker ```docker-compose up -d postgres```\n    - para testar na web: localhost:3000/docs\n  \n  - Caso de erro nas migrations ou caso não consiga inserir algum evento pela docs ou caso você mude a env de conexão com o banco pelo .env, basta dar um ```npm run db:migrate``` ou ```npm run db:migrate-deploy``` para rodar as migrations novamente\n  Apos rodar ira aparecer isso no terminal do vscode:\n  ```bash\n  \n    \u003e api@1.0.0 db:migrate-deploy\n    \u003e prisma migrate deploy\n\n    Environment variables loaded from .env\n    Prisma schema loaded from prisma\\schema.prisma\n    Datasource \"db\": PostgreSQL database \"attendee-postgres\", schema \"public\" at \"attendee-postgres-do-user-16367090-0.c.db.ondigitalocean.com:25060\"\n\n    5 migrations found in prisma/migrations\n\n    Applying migration `20240404175946_create_table_events`\n    Applying migration `20240405204149_create_table_attendees`\n    Applying migration `20240405213357_add_uniqueness_on_event_id_and_email`\n    Applying migration `20240406174022_create_check_ins_table`\n    Applying migration `20240406190256_add_cascades`\n  ```\n\n  Talvez de esse erro, mas não tem problema porque ele ja aplicou as migrations. Mas caso não queria ver esse erro, basta deletar todas as migrations e rodar o ```npm run db:migrate-deploy``` ou ```npm run db:migrate``` novamente. Isso pode estar ocorrendo porque a aplicação no prisma estava com SQlite e agora esta com o postgres\n  ```bash\n      Error: P3018\n\n      A migration failed to apply. New migrations cannot be applied before the error is recovered from. Read more about how to resolve migration issues in a production database: https://pris.ly/d/migrate-resolve\n\n      Migration name: 20240406190256_add_cascades\n\n      Database error code: 42601\n\n      Database error:\n      ERROR: syntax error at or near \"PRAGMA\"\n\n      Position:\n        0\n        1 -- RedefineTables\n        2 PRAGMA foreign_keys=OFF;\n\n      DbError { severity: \"ERROR\", parsed_severity: Some(Error), code: SqlState(E42601), message: \"syntax error at or near \\\"PRAGMA\\\"\", detail: None, hint: None, position: Some(Original(19)), where_: None, schema: None, table: None, column: None, datatype: None, constraint: None, file: Some(\"scan.l\"), line: Some(1241), routine: Some(\"scanner_yyerror\") }\n  ```\n  \n  - Como iniciar a aplicação toda via Docker localmente:\n    - Builda a nossa imagem e ja sobe todos os serviços(containers)```docker-compose up --build -d```\n    - Caso ja tenha buildado a nossa imagem(Dockerfile) da api: ```docker-compose up -d```\n    - para testar na web: localhost:3001/docs\n  \n  - Caso de error de migration no docker ou caso não consiga inserir algum evento pela docs( *\"message\": \"Internal server error!\"*) ou troque a env do BD no docker-compose basta, coloque no script de start do package.json o comando de migration ```npm run db:migrate-deploy \u0026\u0026 node dist/server.mjs``` e no Dockerfile deixar o CMD npm start, para que ao subir o container da api ele execute as migrations e depois inicie a aplicação.\n   - E depois buildar a imagem da api novamente e ja subir os serviços(containers): ```docker-compose up --build -d```\n   -  Caso esteja dando erro no log do container da api com esse comando no start, execute o apenas uma vez buildando a aplicação e em seguida no start deixe somente o ```node dist/server.mjs```\n    - e rode novamente o build da imagem\n    - O que podera acontecer ao rodar o build com o comando ```npm run db:migrate-deploy \u0026\u0026 node dist/server.mjs```\n      - Apos rodar ira aparecer isso no log do docker:\n        ```bash\n        \n          \u003e api@1.0.0 db:migrate-deploy\n          \u003e prisma migrate deploy\n\n          Environment variables loaded from .env\n          Prisma schema loaded from prisma\\schema.prisma\n          Datasource \"db\": PostgreSQL database \"attendee-postgres\", schema \"public\" at \"attendee-postgres-do-user-16367090-0.c.db.ondigitalocean.com:25060\"\n\n          5 migrations found in prisma/migrations\n\n          Applying migration `20240404175946_create_table_events`\n          Applying migration `20240405204149_create_table_attendees`\n          Applying migration `20240405213357_add_uniqueness_on_event_id_and_email`\n          Applying migration `20240406174022_create_check_ins_table`\n          Applying migration `20240406190256_add_cascades`\n        ```\n\n        Talvez de esse erro no log do docker do container da api(api-pass-in), mas não tem problema porque ele ja aplicou as migrations. Mas caso não queria ver esse erro, basta deletar todas as migrations e rodar o ```npm run db:migrate-deploy``` ou ```npm run db:migrate``` novamente localmente, e depois buildar a imagem da api novamente e ja subir os serviços(containers): ```docker-compose up --build -d``` e lembre de deixar o comando no start do package.json ```npm run db:migrate-deploy \u0026\u0026 node dist/server.mjs```. Isso pode estar ocorrendo porque a aplicação no prisma estava com SQlite e agora esta com o postgres\n        ```bash\n            Error: P3018\n\n            A migration failed to apply. New migrations cannot be applied before the error is recovered from. Read more about how to resolve migration issues in a production database: https://pris.ly/d/migrate-resolve\n\n            Migration name: 20240406190256_add_cascades\n\n            Database error code: 42601\n\n            Database error:\n            ERROR: syntax error at or near \"PRAGMA\"\n\n            Position:\n              0\n              1 -- RedefineTables\n              2 PRAGMA foreign_keys=OFF;\n\n            DbError { severity: \"ERROR\", parsed_severity: Some(Error), code: SqlState(E42601), message: \"syntax error at or near \\\"PRAGMA\\\"\", detail: None, hint: None, position: Some(Original(19)), where_: None, schema: None, table: None, column: None, datatype: None, constraint: None, file: Some(\"scan.l\"), line: Some(1241), routine: Some(\"scanner_yyerror\") }\n        ```\n  \n  - Pipeline e actions\n    - [Hands-on: automatização de pipelines de entrega com Github Actions](https://medium.com/itautech/hands-on-automatização-de-pipelines-de-entrega-com-github-actions-1e6a0864f6ce)\n  \n  - Serviço apartado de banco de dados\n    - Um cluster de banco de dados: [digitalocean](https://cloud.digitalocean.com/projects/187bc1eb-cb5f-4710-87f1-8c32ca1d319a/resources?i=db8298)\n      - [Database](https://cloud.digitalocean.com/databases?i=db8298)\n       - [Create Database Cluster](https://cloud.digitalocean.com/databases/new?i=db8298)\n   \n    Não iremos criar o bd diretamente na digitalocean, vamos criar um bd pelo terraform, porque no digitalocen seria algo bem simples, mas ao longo prazo teríamos problemas, por isso iremos criar usando os conceitos de infraestrutura como código(IaC) com o terraform\n    - [Terraform](https://www.terraform.io/)\n     - [Terraform register](https://registry.terraform.io/?product_intent=terraform)\n     - [Browser Providers](https://registry.terraform.io/browse/providers)\n      - Existe varias, como AWS, mas iremos usar a digitalocean\n        - [DigitalOcean](https://registry.terraform.io/providers/digitalocean/digitalocean/latest)\n          - Use Provider\n            ```bash\n            terraform {\n              required_providers {\n                digitalocean = {\n                  source = \"digitalocean/digitalocean\"\n                  version = \"2.36.0\"\n                }\n              }\n            }\n\n            provider \"digitalocean\" {\n              # Configuration options\n              # Passagem de um token associado a nossa conta\n              \n            }\n            ```\n\n\n          - [Documentation](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs)\n           - [digitalocean_database_cluster](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_cluster) Todas as configurações que iriamos passar peo console, passamos agora por aqui: Para a gente criar um cluster: Primeiro configuramos o provider, depois dentro do provedor eu falo que eu quero utilizar o recurso digitalocean_database_cluster, e dentro desse recurso eu passo as configurações(que eu ia passar pelo console da digitalonce) que eu quero para o meu cluster. Esse cluster é para o BD postgres\n            - Exemplo:\n           ```bash\n              resource \"digitalocean_database_cluster\" \"postgres-example\" {\n                name       = \"example-postgres-cluster\"\n                engine     = \"pg\"\n                version    = \"15\"\n                size       = \"db-s-1vcpu-1gb\"\n                region     = \"nyc1\"\n                node_count = 1\n              }\n           ```\n          - Esse é para criar um banco e um cluster para um banco: [digitalocean_database_db](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_db)\n            ```bash\n                # cria um banco em segundo, usando o id do cluster criado\n                resource \"digitalocean_database_db\" \"database-example\" {\n                  cluster_id = digitalocean_database_cluster.postgres-example.id\n                  name       = \"foobar\"\n                }\n                # Cria um cluster primeiro\n                resource \"digitalocean_database_cluster\" \"postgres-example\" {\n                  name       = \"example-postgres-cluster\"\n                  engine     = \"pg\"\n                  version    = \"11\"\n                  size       = \"db-s-1vcpu-1gb\"\n                  region     = \"nyc1\"\n                  node_count = 1\n                }\n            ```\n\n    - Criamos uma pasta para a api e uma para terraform, ou deixa a api na raiz do repositorio e criamos uma pasta para o terraform\n    - Baixe as extensoes do terraform no vscode: [HashiCorp Terraform](https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform), [Terraform](https://marketplace.visualstudio.com/items?itemName=4ops.terraform) e [Terraform Autocomplete](https://marketplace.visualstudio.com/items?itemName=erd0s.terraform-autocomplete)\n    - Lembre de instalar o terraform na maquina: [Terraform](https://developer.hashicorp.com/terraform/install?product_intent=terraform)\n      - [Como instalar](https://www.youtube.com/watch?v=bSrV1Dr8py8)(Lembre de fechar e abrir o terminal para que o terraform seja reconhecido, se não der abre e fechar o vscode)\n    - Agora iremos iniciar o terraform ```terraform init```, lembre de abrir o terminal na pasta do terraform com os arquivos do Terraform, apos isso ele ira gerar *.terraform.lock.hcl*. O terraform init ira iniciar o nosso plugin, procurar ele e instalar\n    - Depois ```terraform fmt``` para ver se os arquivos estão formatados corretamente\n    - Depois ```terraform plan```, ele ira criar a pasta *.terraform*, onde ele cria um plano de execução, ele planifica.\n      ```bash\n        Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:\n          + create\n\n        Terraform will perform the following actions:\n\n          # digitalocean_database_cluster.db-cluster will be created\n          + resource \"digitalocean_database_cluster\" \"db-cluster\" {\n              + database             = (known after apply)\n              + engine               = \"pg\"\n              + host                 = (known after apply)\n              + id                   = (known after apply)\n              + name                 = \"attendee-postgres\"\n              + node_count           = 1\n              + password             = (sensitive value)\n              + port                 = (known after apply)\n              + private_host         = (known after apply)\n              + private_network_uuid = (known after apply)\n              + private_uri          = (sensitive value)\n              + project_id           = (known after apply)\n              + region               = \"nyc1\"\n              + size                 = \"db-s-1vcpu-1gb\"\n              + storage_size_mib     = (known after apply)\n              + uri                  = (sensitive value)\n              + urn                  = (known after apply)\n              + user                 = (known after apply)\n              + version              = \"16\"\n            }\n\n          # digitalocean_database_db.db-name will be created\n          + resource \"digitalocean_database_db\" \"db-name\" {\n              + cluster_id = (known after apply)\n              + id         = (known after apply)\n              + name       = \"attendee-postgres\"\n            }\n\n        Plan: 2 to add, 0 to change, 0 to destroy.\n\n      ```\n      - O plano dele inidica ele vai criar o cluster, depois o BD e no plano dele ele vai adicionar 2 recursos. O terraform é baseado em estado, o famoso tf state, o estado do cluster, é legal que esse arquivo fique em um lugar remoto e não na nossa maquina\n      - Depois ```terraform apply -auto-approve```, ele ira aplicar o plano de execução, o -auto-approve é para não travar o console\n      - Apos isso, ele ira criar o arquivo *terraform.tfstate* e ira criar o nosso cluster\n      - Se você ir na digital once em [database](https://cloud.digitalocean.com/databases?i=db8298), você vera o cluster sendo criado e depois o banco. Apos a criação o tfstate podera ser aberto. E apos a criação teremos um banco de dados remoto. Na parte o overview na digital ocean é possivel ver a senha do banco. digitalocean_database_db.db-name --\u003e banco, digitalocean_database_cluster.db-cluster -\u003e cluster\n      ```bash\n        digitalocean_database_cluster.db-cluster: Creating...\n        digitalocean_database_cluster.db-cluster: Still creating... [10s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [20s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [30s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [40s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [50s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [1m0s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [1m10s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [1m20s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [1m30s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [1m40s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [1m50s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [2m0s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [2m10s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [2m20s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [2m30s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [2m40s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [2m50s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [3m0s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [3m10s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [3m20s elapsed]\n        digitalocean_database_cluster.db-cluster: Still creating... [3m30s elapsed]\n        digitalocean_database_cluster.db-cluster: Creation complete after 3m36s [id=f1a889ad-09e5-48dd-b0f8-d7d89239dcb0]\n        digitalocean_database_db.db-name: Creating...\n        digitalocean_database_db.db-name: Creation complete after 2s [id=f1a889ad-09e5-48dd-b0f8-d7d89239dcb0/database/attendee-postgres]\n\n        Apply complete! Resources: 2 added, 0 changed, 0 destroyed.\n      ```\n      - Agora quando for alterar algo, mudar o plano, colocar mais maquinas, sempre via IaC terraform, nunca manualmente pelo console\n      - Se eu quiser deletar ```terraform plan -destroy``` ou comentar ou tirar o recurso do main.tf e rodar o ```terraform apply -auto-approve```\n      - O terraform se orienta pelo arquivo gerado apos o apply *terraform.tfstate*, logo, se deletarmos ele e rodar um plan, ele vai entender que precisamos criar esses recursos novamente, isso vai gerar uma anomalia, dando problema para criar o mesmo recurso com o mesmo nome...\n      - Agora iremos conectar a nossa aplicação com o banco\n        - Na Digital once Em overview\u003eConnection parameters\u003eConnection strin\u003edatabase/pool:defaultdb\u003eattendee-postgres\u003e copiamos a string de conexão: postgresql://doadmin:SHOW_PASSWORD@attendee-postgres-do-user-16367090-0.c.db.ondigitalocean.com:25060/attendee-postgres?sslmode=require\n        - Podemos testar colocando no env da nossa aplicação em DATABASE_URL, lembre de rodar as migrations apos mudar o env do banco, seja no .env quanto no docker compose(Pode dar os erros que foram listados antes de entrar na parte do terraform ao fazer as migrations tanto com docker mudando o script de start, quanto fora do docker fazendo manual usando o comando de migração do prisma).\n      - Ao tentar enviar os arquivos *terraform.tfstate*, *.terraform.lock.hcl* e a pasta *.terraform* para o github, ele não vai deixar, porque são arquivos sensíveis, logo, devemos criar um arquivo *.gitignore* e colocar esses arquivos la, para que não sejam enviados para o github","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrohvfernandes%2Flearn-to-use-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedrohvfernandes%2Flearn-to-use-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrohvfernandes%2Flearn-to-use-docker/lists"}