{"id":17967185,"url":"https://github.com/leo-henrique/containerized-app-with-docker","last_synced_at":"2026-04-18T06:32:51.734Z","repository":{"id":259493277,"uuid":"878007819","full_name":"Leo-Henrique/containerized-app-with-docker","owner":"Leo-Henrique","description":"Aplicação conteinerizada com o Docker.","archived":false,"fork":false,"pushed_at":"2024-10-25T21:30:48.000Z","size":272,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-09T09:29:16.279Z","etag":null,"topics":["alpine-linux","containers","docker","docker-compose","docker-image","dockerfile","multi-stage-build"],"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/Leo-Henrique.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-10-24T16:02:54.000Z","updated_at":"2024-10-25T21:30:52.000Z","dependencies_parsed_at":"2024-10-26T00:47:24.508Z","dependency_job_id":"e0a97db9-1917-4ef4-a9a7-950a2ca331b0","html_url":"https://github.com/Leo-Henrique/containerized-app-with-docker","commit_stats":null,"previous_names":["leo-henrique/containerized-app-with-docker"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leo-Henrique%2Fcontainerized-app-with-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leo-Henrique%2Fcontainerized-app-with-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leo-Henrique%2Fcontainerized-app-with-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leo-Henrique%2Fcontainerized-app-with-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Leo-Henrique","download_url":"https://codeload.github.com/Leo-Henrique/containerized-app-with-docker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247081325,"owners_count":20880408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["alpine-linux","containers","docker","docker-compose","docker-image","dockerfile","multi-stage-build"],"created_at":"2024-10-29T14:04:28.653Z","updated_at":"2026-04-18T06:32:51.672Z","avatar_url":"https://github.com/Leo-Henrique.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aplicação conteinerizada com Docker\n\nAplicação de exemplo para demonstrar a conteinerização com o Docker.\n\n## Binário da aplicação\n\nO binário da aplicação — um back-end em Node.js — utiliza uma [imagem oficial do Node.js pelo Docker](https://hub.docker.com/_/node) e conta com algumas abordagens para manter um binário otimizado (contendo atualmente **167MB**).\n\n\u003cimg \n  src=\"https://github.com/user-attachments/assets/90b171b0-3e20-4ead-9851-b493e4c17deb\"\n  alt=\"Docker image\"\n/\u003e\n\n### Distro Alpine\n\nO primeiro passo visando a construção de um binário otimizado foi escolher uma versão de imagem do Node.js enxuta e que não contém recursos que sequer são utilizados. As versões Alpine tem origem da [distro Alpine do Linux](https://alpinelinux.org/) e possuem exatamente esse propósito.\n\nEu escolhi a [20.18-alpine](https://hub.docker.com/layers/library/node/20.18-alpine/images/sha256-d504f23acdda979406cf3bdbff0dff7933e5c4ec183dda404ed24286c6125e60?context=explore) que contém apenas **45.42 MB**. Eu também abri mão das versões mais recentes para evitar qualquer possível vulnerabilidade.\n\n### Multi-stage build\n\nAlém do meu back-end em Node.js com TypeScript precisar ser compilado para JavaScript, eu também tenho muitas dependências de desenvolvimento que não fazem diferença alguma em produção.\n\nA estratégia de utilizar múltiplos estágios na construção da imagem no Dockerfile foi fundamental para que eu pudesse resolver esse problema e manter um binário leve.\n\n`./Dockerfile`\n\n```Dockerfile\nFROM base AS prod-deps\nRUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile --ignore-scripts\n\nFROM base AS build\nRUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile --ignore-scripts\nRUN pnpm build\n\nFROM base\nWORKDIR /usr/src/app\n# Copia somente as dependências de produção para a imagem, instaladas no estágio 'prod-deps'\nCOPY --from=prod-deps /usr/src/app/node_modules ./node_modules\n# Copia os arquivos da aplicação para a imagem, construídas no estágio 'build'\nCOPY --from=build /usr/src/app/dist ./dist\nEXPOSE $API_PORT\nCMD [\"pnpm\", \"start\"]\n```\n\n## Rode localmente\n\n### Dependências globais\n\nVocê precisa ter uma principal dependência instalada:\n\n- [Docker](https://www.docker.com/products/docker-desktop/) 24.0.6 (ou qualquer versão superior)\n\n### Clone o projeto\n\n```bash\n# git\ngit clone https://github.com/Leo-Henrique/containerized-app-with-docker.git\n\n# GitHub CLI\ngh repo clone Leo-Henrique/containerized-app-with-docker\n```\n\n### Suba os containers do Docker\n\nDois serviços serão iniciados. Um container conterá um servidor Node.js que usa [node:20.18-alpine](https://hub.docker.com/layers/library/node/20.18-alpine/images/sha256-d504f23acdda979406cf3bdbff0dff7933e5c4ec183dda404ed24286c6125e60?context=explore) como imagem base e outro conterá um banco de dados Postgres que usa [postgres:16-alpine3.18](https://hub.docker.com/layers/library/postgres/16-alpine3.18/images/sha256-79790a9fa3ab75f5f590766d095fdd21cf292f1abbaa834bfe2036585ed0f2e5?context=explore) como imagem base.\n\n```bash\ndocker compose up -d --build\n```\n\n### Verificar logs do container da API\n\n```bash\ndocker compose logs api\n```\n\nSe tudo estiver funcionando, você verá nas últimas linhas dos logs uma mensagem assim:\n\n```bash\ncontainerized-app-with-docker-api       | Application \"containerized-app-with-docker\" is running!\ncontainerized-app-with-docker-api       | http://localhost:3333/docs\n```\n\nComo mostra a mensagem, você conseguirá acessar a documentação da API em: [http://localhost:3333/docs](http://localhost:3333/docs), um servidor em Node.js, sem o próprio Node.js instalado na sua máquina propriamente dita, mas sim, no container (um processo totalmente isolado)!\n\n\u003cimg \n  src=\"https://github.com/user-attachments/assets/a159bbfe-8248-471e-af38-4a4c425ac973\"\n  alt=\"API documentation\"\n/\u003e\n\n**OBS**: Se você já subiu serviços do Docker na sua máquina, talvez seja necessário trocar os endereços e portas que estão sendo mapeados. Você pode alterar as variáveis no arquivo `.env` localizado na raiz do projeto e deve subir os serviços novamente para aplicar as alterações.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleo-henrique%2Fcontainerized-app-with-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleo-henrique%2Fcontainerized-app-with-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleo-henrique%2Fcontainerized-app-with-docker/lists"}