[{"data":1,"prerenderedAt":1215},["ShallowReactive",2],{"navigation_docs":3,"-atividades-atv-17-conteineres-docker":252,"-atividades-atv-17-conteineres-docker-surround":1210},[4,96,189],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"⚙️ Engenharia de Software","i-lucide-book-open","\u002Fengenharia-software","1.engenharia-software",[10,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92],{"title":5,"path":7,"stem":11},"1.engenharia-software\u002Findex",{"title":13,"path":14,"stem":15},"📋 Plano de Ensino e Aplicações","\u002Fengenharia-software\u002Fengenharia-software-aplicacoes","1.engenharia-software\u002F01.engenharia-software-aplicacoes",{"title":17,"path":18,"stem":19},"Cap 01: Introdução e Natureza do Software","\u002Fengenharia-software\u002Fcap-01","1.engenharia-software\u002F02.cap-01",{"title":21,"path":22,"stem":23},"Cap 02: Modelos de Processo de Software","\u002Fengenharia-software\u002Fcap-02","1.engenharia-software\u002F03.cap-02",{"title":25,"path":26,"stem":27},"Cap 03: As Atividades do Processo","\u002Fengenharia-software\u002Fcap-03","1.engenharia-software\u002F04.cap-03",{"title":29,"path":30,"stem":31},"Cap 04: Metodologias Ágeis","\u002Fengenharia-software\u002Fcap-04","1.engenharia-software\u002F05.cap-04",{"title":33,"path":34,"stem":35},"Cap 05: Fundamentos de Requisitos","\u002Fengenharia-software\u002Fcap-05","1.engenharia-software\u002F06.cap-05",{"title":37,"path":38,"stem":39},"Cap 06: Elicitação e Levantamento","\u002Fengenharia-software\u002Fcap-06","1.engenharia-software\u002F07.cap-06",{"title":41,"path":42,"stem":43},"Cap 07: Especificação de Requisitos (ERS)","\u002Fengenharia-software\u002Fcap-07","1.engenharia-software\u002F08.cap-07",{"title":45,"path":46,"stem":47},"Cap 08: Validação e Gestão","\u002Fengenharia-software\u002Fcap-08","1.engenharia-software\u002F09.cap-08",{"title":49,"path":50,"stem":51},"Cap 09: Fundamentos da Modelagem","\u002Fengenharia-software\u002Fcap-09","1.engenharia-software\u002F10.cap-09",{"title":53,"path":54,"stem":55},"Cap 10: Diagrama de Casos de Uso (Conceitos)","\u002Fengenharia-software\u002Fcap-10","1.engenharia-software\u002F11.cap-10",{"title":57,"path":58,"stem":59},"Cap 11: Casos de Uso (Prática e Relações)","\u002Fengenharia-software\u002Fcap-11","1.engenharia-software\u002F12.cap-11",{"title":61,"path":62,"stem":63},"Cap 12: Diagrama de Classes (Conceitos)","\u002Fengenharia-software\u002Fcap-12","1.engenharia-software\u002F13.cap-12",{"title":65,"path":66,"stem":67},"Cap 13: Herança e Polimorfismo","\u002Fengenharia-software\u002Fcap-13","1.engenharia-software\u002F14.cap-13",{"title":69,"path":70,"stem":71},"Cap 14: Diagrama de Sequência","\u002Fengenharia-software\u002Fcap-14","1.engenharia-software\u002F15.cap-14",{"title":73,"path":74,"stem":75},"Cap 15: Diagramas Dinâmicos (Estados e Atividades)","\u002Fengenharia-software\u002Fcap-15","1.engenharia-software\u002F16.cap-15",{"title":77,"path":78,"stem":79},"Cap 16: Qualidade de Software (SQA)","\u002Fengenharia-software\u002Fcap-16","1.engenharia-software\u002F17.cap-16",{"title":81,"path":82,"stem":83},"Cap 17: Estratégias de Teste","\u002Fengenharia-software\u002Fcap-17","1.engenharia-software\u002F18.cap-17",{"title":85,"path":86,"stem":87},"Cap 18: Manutenção e Evolução","\u002Fengenharia-software\u002Fcap-18","1.engenharia-software\u002F19.cap-18",{"title":89,"path":90,"stem":91},"Cap 19: Gerência de Configuração (SCM)","\u002Fengenharia-software\u002Fcap-19","1.engenharia-software\u002F20.cap-19",{"title":93,"path":94,"stem":95},"Cap 20: Conclusão e Próximos Passos","\u002Fengenharia-software\u002Fcap-20","1.engenharia-software\u002F21.cap-20",{"title":97,"icon":98,"path":99,"stem":100,"children":101},"🛠️ Atividades","i-lucide-wrench","\u002Fatividades","2.atividades",[102,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,185],{"title":103,"path":99,"stem":104},"📋 Orientações Gerais","2.atividades\u002Findex",{"title":106,"path":107,"stem":108},"📅 Cronograma","\u002Fatividades\u002Fcronograma","2.atividades\u002F01.cronograma",{"title":110,"path":111,"stem":112},"✏️ Atividade 01: Escopo e Personas","\u002Fatividades\u002Fatv-01-escopo","2.atividades\u002F02.atv-01-escopo",{"title":114,"path":115,"stem":116},"⚙️ Atividade 02: Processos de Software","\u002Fatividades\u002Fatv-02-processos","2.atividades\u002F03.atv-02-processos",{"title":118,"path":119,"stem":120},"📋 Atividade 03: Engenharia de Requisitos","\u002Fatividades\u002Fatv-03-requisitos","2.atividades\u002F04.atv-03-requisitos",{"title":122,"path":123,"stem":124},"📝 Atividade 04: User Stories e Backlog","\u002Fatividades\u002Fatv-04-backlog","2.atividades\u002F05.atv-04-backlog",{"title":126,"path":127,"stem":128},"🎭 Atividade 05: Casos de Uso (UML)","\u002Fatividades\u002Fatv-05-casos-uso","2.atividades\u002F06.atv-05-casos-uso",{"title":130,"path":131,"stem":132},"🖼️ Atividade 06: Prototipagem e Wireframes","\u002Fatividades\u002Fatv-06-prototipagem","2.atividades\u002F07.atv-06-prototipagem",{"title":134,"path":135,"stem":136},"🏛️ Atividade 07: Diagrama de Classes (UML)","\u002Fatividades\u002Fatv-07-classes","2.atividades\u002F08.atv-07-classes",{"title":138,"path":139,"stem":140},"🔀 Atividade 08: Diagrama de Sequência (UML)","\u002Fatividades\u002Fatv-08-sequencia","2.atividades\u002F09.atv-08-sequencia",{"title":142,"path":143,"stem":144},"🧪 Atividade 09: Qualidade e Testes","\u002Fatividades\u002Fatv-09-testes","2.atividades\u002F10.atv-09-testes",{"title":146,"path":147,"stem":148},"🏁 Atividade 10: Projeto Integrador Final","\u002Fatividades\u002Fatv-10-projeto-final","2.atividades\u002F11.atv-10-projeto-final",{"title":150,"path":151,"stem":152},"📊 Atividade 11: Diagrama de Atividades (UML)","\u002Fatividades\u002Fatv-11-atividades","2.atividades\u002F12.atv-11-atividades",{"title":154,"path":155,"stem":156},"🔄 Atividade 12: Diagrama de Transição de Estados (UML)","\u002Fatividades\u002Fatv-12-estados","2.atividades\u002F13.atv-12-estados",{"title":158,"path":159,"stem":160},"🏗️ Atividade 13: Arquitetura de Software e Padrões","\u002Fatividades\u002Fatv-13-arquitetura","2.atividades\u002F14.atv-13-arquitetura",{"title":162,"path":163,"stem":164},"🌐 Atividade 14: Modelagem de APIs REST e Swagger","\u002Fatividades\u002Fatv-14-apis-swagger","2.atividades\u002F15.atv-14-apis-swagger",{"title":166,"path":167,"stem":168},"🌿 Atividade 15: GitFlow e Trabalho Colaborativo","\u002Fatividades\u002Fatv-15-gitflow-colaboracao","2.atividades\u002F16.atv-15-gitflow-colaboracao",{"title":170,"path":171,"stem":172},"🚀 Atividade 16: Pipelines de CI\u002FCD com GitHub Actions","\u002Fatividades\u002Fatv-16-pipelines-cicd","2.atividades\u002F17.atv-16-pipelines-cicd",{"title":174,"path":175,"stem":176},"🐳 Atividade 17: Containerização de Ambientes com Docker","\u002Fatividades\u002Fatv-17-conteineres-docker","2.atividades\u002F18.atv-17-conteineres-docker",{"title":178,"path":179,"stem":180},"🔒 Atividade 18: Segurança no Desenvolvimento e OWASP","\u002Fatividades\u002Fatv-18-seguranca-devsecops","2.atividades\u002F19.atv-18-seguranca-devsecops",{"title":182,"path":183,"stem":184},"📈 Atividade 19: Métricas de Software, Estimativas e DORA","\u002Fatividades\u002Fatv-19-metricas-estimativas","2.atividades\u002F20.atv-19-metricas-estimativas",{"title":186,"path":187,"stem":188},"🏆 Atividade 20: Projeto Final Avançado (Fase 2)","\u002Fatividades\u002Fatv-20-projeto-final-avancado","2.atividades\u002F21.atv-20-projeto-final-avancado",{"title":190,"icon":191,"path":192,"stem":193,"children":194},"🖼️ Galeria de Projetos Integradores","i-lucide-image","\u002Fprojetos-integradores","3.projetos-integradores",[195,197,207,216,225,234,243],{"title":190,"path":192,"stem":196},"3.projetos-integradores\u002Findex",{"title":198,"path":199,"stem":200,"children":201},"🅿️ Projeto 01: Gestão de Estacionamentos","\u002Fprojetos-integradores\u002Fpi-01-gestao-estacionamentos","3.projetos-integradores\u002F01.pi-01-gestao-estacionamentos\u002Findex",[202,203],{"title":198,"path":199,"stem":200},{"title":204,"path":205,"stem":206},"README","\u002Fprojetos-integradores\u002Fpi-01-gestao-estacionamentos\u002Freadme","3.projetos-integradores\u002F01.pi-01-gestao-estacionamentos\u002F2.readme",{"title":208,"path":209,"stem":210,"children":211},"🔐 Projeto 02: Gerador de Senhas","\u002Fprojetos-integradores\u002Fpi-02-gerador-senhas","3.projetos-integradores\u002F02.pi-02-gerador-senhas\u002Findex",[212,213],{"title":208,"path":209,"stem":210},{"title":204,"path":214,"stem":215},"\u002Fprojetos-integradores\u002Fpi-02-gerador-senhas\u002Freadme","3.projetos-integradores\u002F02.pi-02-gerador-senhas\u002F2.readme",{"title":217,"path":218,"stem":219,"children":220},"🍣 Projeto 03: Pedidos Restaurante","\u002Fprojetos-integradores\u002Fpi-03-pedidos-restaurante","3.projetos-integradores\u002F03.pi-03-pedidos-restaurante\u002Findex",[221,222],{"title":217,"path":218,"stem":219},{"title":204,"path":223,"stem":224},"\u002Fprojetos-integradores\u002Fpi-03-pedidos-restaurante\u002Freadme","3.projetos-integradores\u002F03.pi-03-pedidos-restaurante\u002F2.readme",{"title":226,"path":227,"stem":228,"children":229},"📱 Projeto 04: Empréstimos Dispositivos","\u002Fprojetos-integradores\u002Fpi-04-emprestimos-dispositivos","3.projetos-integradores\u002F04.pi-04-emprestimos-dispositivos\u002Findex",[230,231],{"title":226,"path":227,"stem":228},{"title":204,"path":232,"stem":233},"\u002Fprojetos-integradores\u002Fpi-04-emprestimos-dispositivos\u002Freadme","3.projetos-integradores\u002F04.pi-04-emprestimos-dispositivos\u002F2.readme",{"title":235,"path":236,"stem":237,"children":238},"📦 Projeto 05: Gestão de Estoque","\u002Fprojetos-integradores\u002Fpi-05-gestao-estoque","3.projetos-integradores\u002F05.pi-05-gestao-estoque\u002Findex",[239,240],{"title":235,"path":236,"stem":237},{"title":204,"path":241,"stem":242},"\u002Fprojetos-integradores\u002Fpi-05-gestao-estoque\u002Freadme","3.projetos-integradores\u002F05.pi-05-gestao-estoque\u002F2.readme",{"title":244,"path":245,"stem":246,"children":247},"🛵 Projeto 06: Aplicativo de Delivery","\u002Fprojetos-integradores\u002Fpi-06-delivery","3.projetos-integradores\u002F06.pi-06-delivery\u002Findex",[248,249],{"title":244,"path":245,"stem":246},{"title":204,"path":250,"stem":251},"\u002Fprojetos-integradores\u002Fpi-06-delivery\u002Freadme","3.projetos-integradores\u002F06.pi-06-delivery\u002F2.readme",{"id":253,"title":174,"body":254,"description":1204,"extension":1205,"links":1206,"meta":1207,"navigation":445,"path":175,"seo":1208,"stem":176,"__hash__":1209},"docs\u002F2.atividades\u002F18.atv-17-conteineres-docker.md",{"type":255,"value":256,"toc":1184},"minimark",[257,270,273,278,281,313,315,319,326,343,345,349,379,384,388,390,394,397,405,411,572,579,585,960,962,966,972,988,992,995,997,1001,1006,1020,1022,1026,1029,1048,1050,1054,1092,1094,1098,1180],[258,259,260,261,265,266,269],"p",{},"Hoje, aprenderemos sobre ",[262,263,264],"strong",{},"Docker"," e ",[262,267,268],{},"Docker Compose",", as tecnologias líderes de mercado que revolucionaram a forma de empacotar, distribuir e rodar aplicações em ambientes isolados e idênticos, garantindo previsibilidade absoluta! 🚀",[271,272],"hr",{},[274,275,277],"h2",{"id":276},"objetivo-da-aula","🎯 Objetivo da Aula",[258,279,280],{},"Ao final desta atividade, você será capaz de:",[282,283,284,296,303,310],"ul",{},[285,286,287,288,291,292,295],"li",{},"Compreender os conceitos fundamentais de ",[262,289,290],{},"Contêineres"," vs ",[262,293,294],{},"Máquinas Virtuais",".",[285,297,298,299,302],{},"Escrever um ",[262,300,301],{},"Dockerfile"," otimizado para empacotar uma aplicação web Java 17 com Spring Boot.",[285,304,305,306,309],{},"Criar um arquivo ",[262,307,308],{},"docker-compose.yml"," para orquestrar múltiplos contêineres (App + PostgreSQL) em rede local isolada.",[285,311,312],{},"Gerenciar redes virtuais e volumes persistentes no ambiente Docker.",[271,314],{},[274,316,318],{"id":317},"o-cenário-prático-seu-desafio","🏢 O Cenário Prático (Seu Desafio)",[258,320,321,322,325],{},"Na ",[262,323,324],{},"TecProExpress",", a equipe de desenvolvimento estava enfrentando um caos diário de configuração. Cada desenvolvedor usava uma versão diferente do Java, um usava MySQL local, outro usava PostgreSQL, e um terceiro usava uma versão desatualizada do banco de dados que quebrava as chaves estrangeiras. A contratação de novos programadores demorava até 3 dias apenas para configurar o ambiente de desenvolvimento local!",[327,328,329],"blockquote",{},[258,330,331,332,335,336,339,340,342],{},"\"Seu desafio como ",[262,333,334],{},"Arquiteto de Soluções"," é padronizar e automatizar 100% do ambiente da TecProExpress. Você criará o arquivo ",[337,338,301],"code",{}," da aplicação web (Java 17, Spring Boot, Thymeleaf e HTMX) e um arquivo ",[337,341,308],{}," que sobe, com um único comando, o servidor da aplicação e o banco de dados PostgreSQL configurados para conversar entre si em uma rede virtual isolada.\"",[271,344],{},[274,346,348],{"id":347},"fundamentos-a-teoria-traduzida","🧠 Fundamentos: A Teoria Traduzida",[282,350,351,357,363,369],{},[285,352,353,356],{},[262,354,355],{},"Imagem Docker:"," É um pacote imutável e somente-leitura que contém tudo o que é necessário para rodar a aplicação (código, dependências, runtime do Java, variáveis de ambiente e arquivos).",[285,358,359,362],{},[262,360,361],{},"Contêiner Docker:"," É a instância em execução de uma imagem. Ele compartilha o kernel do sistema operacional do host, tornando-o extremamente leve, rápido e com consumo mínimo de memória.",[285,364,365,368],{},[262,366,367],{},"Dockerfile:"," O script com comandos sequenciais para construir a Imagem do contêiner.",[285,370,371,374,375,378],{},[262,372,373],{},"Docker Compose:"," A ferramenta que permite definir e rodar aplicações multi-contêiner. Com um único comando (",[337,376,377],{},"docker-compose up","), todas as dependências (banco, cache, app) sobem prontas.",[380,381,383],"h4",{"id":382},"arquitetura-do-ambiente-orquestrado-com-docker","📊 Arquitetura do Ambiente Orquestrado com Docker",[385,386],"mermaid",{"code":387},"flowchart TD\n    subgraph Host [\"Máquina do Desenvolvedor (Host OS)\"]\n        direction TB\n        subgraph DockerNet [\"Rede Virtual Isolada (tecpro-network)\"]\n            direction LR\n            App[\"Contêiner Application: Spring Boot + Thymeleaf\"] \u003C-->|Porta 5432| DB[(\"Contêiner Database: PostgreSQL 15\")]\n        end\n        PortApp[\"Porta Física Exposta: 8080\"] \u003C-->|Direciona Requisições| App\n    end\n    \n    subgraph Persistencia [\"Armazenamento Externo\"]\n        Volume[(\"Volume Docker: pgdata\")] \u003C---> DB\n    end\n\n    style Host fill:#f5f7fa,stroke:#333,stroke-width:2px\n    style DockerNet fill:#e1f5fe,stroke:#0288d1,stroke-width:2px\n    style Persistencia fill:#fff3e0,stroke:#ef6c00,stroke-width:2px\n    style App fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px\n    style DB fill:#ffe0b2,stroke:#f57c00,stroke-width:2px\n",[271,389],{},[274,391,393],{"id":392},"exemplo-guiado-dockerização-de-ponta-a-ponta","📖 Exemplo Guiado: Dockerização de Ponta a Ponta",[258,395,396],{},"Para empacotarmos a aplicação Spring Boot 3.5.x da TecProExpress integrada ao PostgreSQL, utilizaremos a estratégia recomendada de infraestrutura como código.",[398,399,401,402,404],"h3",{"id":400},"_1-️-o-arquivo-dockerfile-da-aplicação","1. 🛠️ O Arquivo ",[337,403,301],{}," da Aplicação",[258,406,407,408,410],{},"Criamos um arquivo com o nome exato ",[337,409,301],{}," (sem extensão) na raiz do projeto Java para definir a construção da nossa imagem:",[412,413,418],"pre",{"className":414,"code":415,"language":416,"meta":417,"style":417},"language-dockerfile shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Etapa 1: Construção (Build) utilizando o Maven oficial com Java 17\nFROM maven:3.8.8-eclipse-temurin-17 AS builder\nWORKDIR \u002Fapp\n\n# Copia os arquivos de configuração do Maven e o código fonte\nCOPY pom.xml .\nCOPY src .\u002Fsrc\n\n# Compila o projeto e gera o arquivo JAR executável ignorando os testes (já rodados no CI)\nRUN mvn clean package -DskipTests\n\n# Etapa 2: Execução (Runtime) com imagem leve JRE\nFROM eclipse-temurin:17-jre-alpine\nWORKDIR \u002Fapp\n\n# Copia o JAR compilado da primeira etapa para o ambiente final\nCOPY --from=builder \u002Fapp\u002Ftarget\u002F*.jar app.jar\n\n# Expõe a porta padrão do Spring Boot\nEXPOSE 8080\n\n# Variáveis de ambiente padrão (podem ser sobrescritas pelo Compose)\nENV SPRING_PROFILES_ACTIVE=prod\n\n# Comando para iniciar a aplicação\nENTRYPOINT [\"java\", \"-jar\", \"app.jar\"]\n","dockerfile","",[337,419,420,428,434,440,447,453,459,465,470,476,482,487,493,499,504,509,515,521,526,532,538,543,549,555,560,566],{"__ignoreMap":417},[421,422,425],"span",{"class":423,"line":424},"line",1,[421,426,427],{},"# Etapa 1: Construção (Build) utilizando o Maven oficial com Java 17\n",[421,429,431],{"class":423,"line":430},2,[421,432,433],{},"FROM maven:3.8.8-eclipse-temurin-17 AS builder\n",[421,435,437],{"class":423,"line":436},3,[421,438,439],{},"WORKDIR \u002Fapp\n",[421,441,443],{"class":423,"line":442},4,[421,444,446],{"emptyLinePlaceholder":445},true,"\n",[421,448,450],{"class":423,"line":449},5,[421,451,452],{},"# Copia os arquivos de configuração do Maven e o código fonte\n",[421,454,456],{"class":423,"line":455},6,[421,457,458],{},"COPY pom.xml .\n",[421,460,462],{"class":423,"line":461},7,[421,463,464],{},"COPY src .\u002Fsrc\n",[421,466,468],{"class":423,"line":467},8,[421,469,446],{"emptyLinePlaceholder":445},[421,471,473],{"class":423,"line":472},9,[421,474,475],{},"# Compila o projeto e gera o arquivo JAR executável ignorando os testes (já rodados no CI)\n",[421,477,479],{"class":423,"line":478},10,[421,480,481],{},"RUN mvn clean package -DskipTests\n",[421,483,485],{"class":423,"line":484},11,[421,486,446],{"emptyLinePlaceholder":445},[421,488,490],{"class":423,"line":489},12,[421,491,492],{},"# Etapa 2: Execução (Runtime) com imagem leve JRE\n",[421,494,496],{"class":423,"line":495},13,[421,497,498],{},"FROM eclipse-temurin:17-jre-alpine\n",[421,500,502],{"class":423,"line":501},14,[421,503,439],{},[421,505,507],{"class":423,"line":506},15,[421,508,446],{"emptyLinePlaceholder":445},[421,510,512],{"class":423,"line":511},16,[421,513,514],{},"# Copia o JAR compilado da primeira etapa para o ambiente final\n",[421,516,518],{"class":423,"line":517},17,[421,519,520],{},"COPY --from=builder \u002Fapp\u002Ftarget\u002F*.jar app.jar\n",[421,522,524],{"class":423,"line":523},18,[421,525,446],{"emptyLinePlaceholder":445},[421,527,529],{"class":423,"line":528},19,[421,530,531],{},"# Expõe a porta padrão do Spring Boot\n",[421,533,535],{"class":423,"line":534},20,[421,536,537],{},"EXPOSE 8080\n",[421,539,541],{"class":423,"line":540},21,[421,542,446],{"emptyLinePlaceholder":445},[421,544,546],{"class":423,"line":545},22,[421,547,548],{},"# Variáveis de ambiente padrão (podem ser sobrescritas pelo Compose)\n",[421,550,552],{"class":423,"line":551},23,[421,553,554],{},"ENV SPRING_PROFILES_ACTIVE=prod\n",[421,556,558],{"class":423,"line":557},24,[421,559,446],{"emptyLinePlaceholder":445},[421,561,563],{"class":423,"line":562},25,[421,564,565],{},"# Comando para iniciar a aplicação\n",[421,567,569],{"class":423,"line":568},26,[421,570,571],{},"ENTRYPOINT [\"java\", \"-jar\", \"app.jar\"]\n",[398,573,575,576,578],{"id":574},"_2-o-arquivo-docker-composeyml-de-orquestração","2. 📄 O Arquivo ",[337,577,308],{}," de Orquestração",[258,580,581,582,584],{},"Na mesma raiz do projeto, criamos o arquivo ",[337,583,308],{}," para conectar a nossa aplicação ao banco de dados PostgreSQL de forma indestrutível:",[412,586,590],{"className":587,"code":588,"language":589,"meta":417,"style":417},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","version: '3.8'\n\nservices:\n  # Serviço 1: Banco de Dados PostgreSQL\n  database:\n    image: postgres:15-alpine\n    container_name: tecpro-db\n    restart: always\n    environment:\n      POSTGRES_DB: tecproexpress\n      POSTGRES_USER: tecpro_admin\n      POSTGRES_PASSWORD: SenhaSuperSegura123\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pgdata:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n    networks:\n      - tecpro-network\n\n  # Serviço 2: Aplicação Java Spring Boot\n  web-app:\n    build: .\n    container_name: tecpro-web-app\n    restart: always\n    ports:\n      - \"8080:8080\"\n    environment:\n      - SPRING_DATASOURCE_URL=jdbc:postgresql:\u002F\u002Fdatabase:5432\u002Ftecproexpress\n      - SPRING_DATASOURCE_USERNAME=tecpro_admin\n      - SPRING_DATASOURCE_PASSWORD=SenhaSuperSegura123\n      - SPRING_JPA_DATABASE-PLATFORM=org.hibernate.dialect.PostgreSQLDialect\n      - SPRING_JPA_HIBERNATE_DDL_AUTO=update\n    depends_on:\n      - database\n    networks:\n      - tecpro-network\n\n# Definição dos Recursos Compartilhados\nvolumes:\n  pgdata:\n    driver: local\n\nnetworks:\n  tecpro-network:\n    driver: bridge\n","yaml",[337,591,592,612,616,624,630,637,647,657,667,674,684,694,704,711,725,732,739,746,753,757,762,769,780,789,797,803,814,821,829,837,845,853,861,869,877,884,891,896,902,910,918,929,934,942,950],{"__ignoreMap":417},[421,593,594,598,602,605,609],{"class":423,"line":424},[421,595,597],{"class":596},"swJcz","version",[421,599,601],{"class":600},"sMK4o",":",[421,603,604],{"class":600}," '",[421,606,608],{"class":607},"sfazB","3.8",[421,610,611],{"class":600},"'\n",[421,613,614],{"class":423,"line":430},[421,615,446],{"emptyLinePlaceholder":445},[421,617,618,621],{"class":423,"line":436},[421,619,620],{"class":596},"services",[421,622,623],{"class":600},":\n",[421,625,626],{"class":423,"line":442},[421,627,629],{"class":628},"sHwdD","  # Serviço 1: Banco de Dados PostgreSQL\n",[421,631,632,635],{"class":423,"line":449},[421,633,634],{"class":596},"  database",[421,636,623],{"class":600},[421,638,639,642,644],{"class":423,"line":455},[421,640,641],{"class":596},"    image",[421,643,601],{"class":600},[421,645,646],{"class":607}," postgres:15-alpine\n",[421,648,649,652,654],{"class":423,"line":461},[421,650,651],{"class":596},"    container_name",[421,653,601],{"class":600},[421,655,656],{"class":607}," tecpro-db\n",[421,658,659,662,664],{"class":423,"line":467},[421,660,661],{"class":596},"    restart",[421,663,601],{"class":600},[421,665,666],{"class":607}," always\n",[421,668,669,672],{"class":423,"line":472},[421,670,671],{"class":596},"    environment",[421,673,623],{"class":600},[421,675,676,679,681],{"class":423,"line":478},[421,677,678],{"class":596},"      POSTGRES_DB",[421,680,601],{"class":600},[421,682,683],{"class":607}," tecproexpress\n",[421,685,686,689,691],{"class":423,"line":484},[421,687,688],{"class":596},"      POSTGRES_USER",[421,690,601],{"class":600},[421,692,693],{"class":607}," tecpro_admin\n",[421,695,696,699,701],{"class":423,"line":489},[421,697,698],{"class":596},"      POSTGRES_PASSWORD",[421,700,601],{"class":600},[421,702,703],{"class":607}," SenhaSuperSegura123\n",[421,705,706,709],{"class":423,"line":495},[421,707,708],{"class":596},"    ports",[421,710,623],{"class":600},[421,712,713,716,719,722],{"class":423,"line":501},[421,714,715],{"class":600},"      -",[421,717,718],{"class":600}," \"",[421,720,721],{"class":607},"5432:5432",[421,723,724],{"class":600},"\"\n",[421,726,727,730],{"class":423,"line":506},[421,728,729],{"class":596},"    volumes",[421,731,623],{"class":600},[421,733,734,736],{"class":423,"line":511},[421,735,715],{"class":600},[421,737,738],{"class":607}," pgdata:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n",[421,740,741,744],{"class":423,"line":517},[421,742,743],{"class":596},"    networks",[421,745,623],{"class":600},[421,747,748,750],{"class":423,"line":523},[421,749,715],{"class":600},[421,751,752],{"class":607}," tecpro-network\n",[421,754,755],{"class":423,"line":528},[421,756,446],{"emptyLinePlaceholder":445},[421,758,759],{"class":423,"line":534},[421,760,761],{"class":628},"  # Serviço 2: Aplicação Java Spring Boot\n",[421,763,764,767],{"class":423,"line":540},[421,765,766],{"class":596},"  web-app",[421,768,623],{"class":600},[421,770,771,774,776],{"class":423,"line":545},[421,772,773],{"class":596},"    build",[421,775,601],{"class":600},[421,777,779],{"class":778},"sbssI"," .\n",[421,781,782,784,786],{"class":423,"line":551},[421,783,651],{"class":596},[421,785,601],{"class":600},[421,787,788],{"class":607}," tecpro-web-app\n",[421,790,791,793,795],{"class":423,"line":557},[421,792,661],{"class":596},[421,794,601],{"class":600},[421,796,666],{"class":607},[421,798,799,801],{"class":423,"line":562},[421,800,708],{"class":596},[421,802,623],{"class":600},[421,804,805,807,809,812],{"class":423,"line":568},[421,806,715],{"class":600},[421,808,718],{"class":600},[421,810,811],{"class":607},"8080:8080",[421,813,724],{"class":600},[421,815,817,819],{"class":423,"line":816},27,[421,818,671],{"class":596},[421,820,623],{"class":600},[421,822,824,826],{"class":423,"line":823},28,[421,825,715],{"class":600},[421,827,828],{"class":607}," SPRING_DATASOURCE_URL=jdbc:postgresql:\u002F\u002Fdatabase:5432\u002Ftecproexpress\n",[421,830,832,834],{"class":423,"line":831},29,[421,833,715],{"class":600},[421,835,836],{"class":607}," SPRING_DATASOURCE_USERNAME=tecpro_admin\n",[421,838,840,842],{"class":423,"line":839},30,[421,841,715],{"class":600},[421,843,844],{"class":607}," SPRING_DATASOURCE_PASSWORD=SenhaSuperSegura123\n",[421,846,848,850],{"class":423,"line":847},31,[421,849,715],{"class":600},[421,851,852],{"class":607}," SPRING_JPA_DATABASE-PLATFORM=org.hibernate.dialect.PostgreSQLDialect\n",[421,854,856,858],{"class":423,"line":855},32,[421,857,715],{"class":600},[421,859,860],{"class":607}," SPRING_JPA_HIBERNATE_DDL_AUTO=update\n",[421,862,864,867],{"class":423,"line":863},33,[421,865,866],{"class":596},"    depends_on",[421,868,623],{"class":600},[421,870,872,874],{"class":423,"line":871},34,[421,873,715],{"class":600},[421,875,876],{"class":607}," database\n",[421,878,880,882],{"class":423,"line":879},35,[421,881,743],{"class":596},[421,883,623],{"class":600},[421,885,887,889],{"class":423,"line":886},36,[421,888,715],{"class":600},[421,890,752],{"class":607},[421,892,894],{"class":423,"line":893},37,[421,895,446],{"emptyLinePlaceholder":445},[421,897,899],{"class":423,"line":898},38,[421,900,901],{"class":628},"# Definição dos Recursos Compartilhados\n",[421,903,905,908],{"class":423,"line":904},39,[421,906,907],{"class":596},"volumes",[421,909,623],{"class":600},[421,911,913,916],{"class":423,"line":912},40,[421,914,915],{"class":596},"  pgdata",[421,917,623],{"class":600},[421,919,921,924,926],{"class":423,"line":920},41,[421,922,923],{"class":596},"    driver",[421,925,601],{"class":600},[421,927,928],{"class":607}," local\n",[421,930,932],{"class":423,"line":931},42,[421,933,446],{"emptyLinePlaceholder":445},[421,935,937,940],{"class":423,"line":936},43,[421,938,939],{"class":596},"networks",[421,941,623],{"class":600},[421,943,945,948],{"class":423,"line":944},44,[421,946,947],{"class":596},"  tecpro-network",[421,949,623],{"class":600},[421,951,953,955,957],{"class":423,"line":952},45,[421,954,923],{"class":596},[421,956,601],{"class":600},[421,958,959],{"class":607}," bridge\n",[271,961],{},[274,963,965],{"id":964},"️-prática-obrigatória-1-desenho-da-rede-de-contêineres","🛠️ Prática Obrigatória 1: Desenho da Rede de Contêineres",[258,967,968,971],{},[262,969,970],{},"Cenário:"," Mapeamento conceitual do ecossistema de contêineres e fluxo de comunicação.",[973,974,975,982,985],"ol",{},[285,976,977,978,981],{},"Desenhe um diagrama ",[337,979,980],{},"flowchart"," no Mermaid representando a arquitetura dos contêineres da sua aplicação.",[285,983,984],{},"Destaque as portas físicas do Host (computador físico) expostas e como elas se mapeiam para as portas internas dos contêineres do Docker.",[285,986,987],{},"Evidencie a comunicação interna entre a aplicação e o banco PostgreSQL utilizando a rede virtualizada privada.",[398,989,991],{"id":990},"resultado-esperado-para-sua-referência","🏁 Resultado Esperado (Para sua Referência)",[258,993,994],{},"Um diagrama visual nítido exibindo o redirecionamento de portas (port-forwarding), volumes de persistência e a barreira da rede virtual.",[271,996],{},[274,998,1000],{"id":999},"️-prática-obrigatória-2-criando-os-arquivos-de-configuração","🛠️ Prática Obrigatória 2: Criando os Arquivos de Configuração",[258,1002,1003,1005],{},[262,1004,970],{}," Escrevendo os scripts de containerização para o seu projeto semestral.",[973,1007,1008,1014],{},[285,1009,1010,1011,1013],{},"Escreva o script ",[337,1012,301],{}," personalizado para o seu sistema de grupo, adaptando caso seu ecossistema necessite de variáveis ou passos específicos.",[285,1015,1016,1017,1019],{},"Escreva o arquivo ",[337,1018,308],{}," que orquestra a aplicação de vocês integrada com um banco de dados persistido e mapeamento de portas do host para o contêiner.",[271,1021],{},[274,1023,1025],{"id":1024},"instruções-de-entrega-microsoft-teams","📤 Instruções de Entrega (Microsoft Teams)",[258,1027,1028],{},"Após projetar a sua infraestrutura containerizada:",[973,1030,1031,1042,1045],{},[285,1032,1033,1034,1037,1038,1041],{},"Salve o arquivo de especificações e códigos com o nome ",[337,1035,1036],{},"Atividade_17.md"," na pasta ",[337,1039,1040],{},"es-atv-17-conteineres-docker\u002F"," do seu repositório GitHub.",[285,1043,1044],{},"Certifique-se de fazer o commit e push para o repositório público.",[285,1046,1047],{},"Submeta o link do seu repositório no Microsoft Teams para avaliação do professor.",[271,1049],{},[274,1051,1053],{"id":1052},"checkpoint-de-lógica","💡 Checkpoint de Lógica",[1055,1056,1059,1062,1063,1066,1067,1069,1070,1073,1074,1077,1078,1081,1082,1084,1085,1087,1088,1091],"callout",{"color":1057,"icon":1058},"primary","i-lucide-megaphone",[262,1060,1061],{},"Importante:"," ",[262,1064,1065],{},"Reflexão Profissional:","\nNo arquivo ",[337,1068,308],{},", a URL de conexão do banco de dados na aplicação web foi definida como ",[337,1071,1072],{},"jdbc:postgresql:\u002F\u002Fdatabase:5432\u002Ftecproexpress"," em vez de ",[337,1075,1076],{},"jdbc:postgresql:\u002F\u002Flocalhost:5432\u002Ftecproexpress",". Por que a palavra ",[337,1079,1080],{},"database"," funciona ali dentro do Docker? E o que aconteceria com os dados do banco de dados do PostgreSQL quando o contêiner fosse deletado e recriado, considerando que usamos a seção ",[337,1083,907],{},"? (Respostas: O Docker possui um DNS embutido em suas redes virtuais que resolve o nome do serviço do Compose — no caso, ",[337,1086,1080],{}," — diretamente para o IP interno dinâmico do contêiner do Postgres. Graças à declaração do volume ",[337,1089,1090],{},"pgdata"," mapeado para a pasta física de arquivos do host, os dados bancários permanecem intactos e persistem mesmo que o contêiner do Postgres seja totalmente destruído e recriado). 🐳💾🧠",[271,1093],{},[274,1095,1097],{"id":1096},"rubrica-formativa-de-avaliação","📊 Rubrica Formativa de Avaliação",[1099,1100,1102,1103,1102,1126],"table",{"style":1101},"width:100%; border-collapse: collapse; font-family: sans-serif; margin: 20px 0; border: 1px solid #ddd; box-shadow: 0 4px 8px rgba(0,0,0,0.1);","\n  ",[1104,1105,1106,1107,1102],"thead",{},"\n    ",[1108,1109,1111,1112,1111,1117,1111,1120,1111,1123,1106],"tr",{"style":1110},"background-color: #2c3e50; color: white;","\n      ",[1113,1114,1116],"th",{"style":1115},"padding: 12px; border: 1px solid #ddd; text-align: left;","Critério de Avaliação",[1113,1118,1119],{"style":1115},"Insuficiente (0% - 40%)",[1113,1121,1122],{"style":1115},"Regular (41% - 70%)",[1113,1124,1125],{"style":1115},"Excelente (71% - 100%)",[1127,1128,1106,1129,1106,1148,1106,1164,1102],"tbody",{},[1108,1130,1111,1132,1111,1139,1111,1142,1111,1145,1106],{"style":1131},"background-color: #f8f9fa;",[1133,1134,1136],"td",{"style":1135},"padding: 10px; border: 1px solid #ddd;",[262,1137,1138],{},"Containerização & Multi-stage Build (Dockerfile)",[1133,1140,1141],{"style":1135},"Dockerfile com sintaxe incorreta ou gerando imagens pesadas sem isolamento de build.",[1133,1143,1144],{"style":1135},"Escreve o Dockerfile mas sem utilizar a técnica de Multi-stage build.",[1133,1146,1147],{"style":1135},"Dockerfile impecável utilizando Multi-stage Build (compilação leve com Maven\u002FJDK e runtime enxuto JRE Alpine).",[1108,1149,1111,1150,1111,1155,1111,1158,1111,1161,1106],{},[1133,1151,1152],{"style":1135},[262,1153,1154],{},"Orquestração Multi-serviço (Docker Compose)",[1133,1156,1157],{"style":1135},"Erros na sintaxe YAML do `docker-compose.yml` ou ausência de mapeamento de portas e volumes.",[1133,1159,1160],{"style":1135},"Orquestra a aplicação e o banco mas esquece da persistência em `volumes`.",[1133,1162,1163],{"style":1135},"Compose perfeito com serviços orquestrados (`depends_on`), variáveis de ambiente atreladas ao DNS do Docker e volume persistente de banco.",[1108,1165,1111,1166,1111,1171,1111,1174,1111,1177,1106],{"style":1131},[1133,1167,1168],{"style":1135},[262,1169,1170],{},"Entrega no GitHub",[1133,1172,1173],{"style":1135},"Entrega fora da pasta `es-atv-17-conteineres-docker\u002F`.",[1133,1175,1176],{"style":1135},"Arquivo entregue sem a explicação da rede virtual do Compose.",[1133,1178,1179],{"style":1135},"Submete `Atividade_17.md` contendo Dockerfile, Compose YAML e diagrama Mermaid de portas\u002Fredes formatados.",[1181,1182,1183],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":417,"searchDepth":430,"depth":436,"links":1185},[1186,1187,1188,1191,1197,1200,1201,1202,1203],{"id":276,"depth":430,"text":277},{"id":317,"depth":430,"text":318},{"id":347,"depth":430,"text":348,"children":1189},[1190],{"id":382,"depth":442,"text":383},{"id":392,"depth":430,"text":393,"children":1192},[1193,1195],{"id":400,"depth":436,"text":1194},"1. 🛠️ O Arquivo Dockerfile da Aplicação",{"id":574,"depth":436,"text":1196},"2. 📄 O Arquivo docker-compose.yml de Orquestração",{"id":964,"depth":430,"text":965,"children":1198},[1199],{"id":990,"depth":436,"text":991},{"id":999,"depth":430,"text":1000},{"id":1024,"depth":430,"text":1025},{"id":1052,"depth":430,"text":1053},{"id":1096,"depth":430,"text":1097},"Bem-vindo a mais uma etapa prática da sua jornada na Engenharia de Software! Após automatizarmos nossos testes no pipeline de CI\u002FCD, agora resolveremos um dos problemas mais clássicos e irritantes no desenvolvimento de software: \"Na minha máquina funciona, por que não funciona no servidor de produção?\" 🤦‍♂️💻","md",null,{},{"title":174,"description":1204},"d6C2CmZrwhnZeyIlrlgoihwMVjhR9V9FuD020diMLgg",[1211,1213],{"title":170,"path":171,"stem":172,"description":1212,"children":-1},"Bem-vindo a mais uma etapa da sua jornada na Engenharia de Software! Nas atividades anteriores, aprendemos sobre GitFlow e arquitetura. Hoje, daremos um passo fundamental na automação de processos industriais de software: a Integração Contínua (CI). Aprenderemos como automatizar a compilação e execução de testes JUnit a cada Push que seu time faz para o repositório, garantindo blindagem contra códigos bugados! 🛡️🧩",{"title":178,"path":179,"stem":180,"description":1214,"children":-1},"Bem-vindo a mais uma etapa crítica da sua jornada na Engenharia de Software! Até aqui, aprendemos a modelar, testar, automatizar e containerizar sistemas. Mas de que adianta um sistema incrivelmente rápido, com CI\u002FCD verde e rodando em Docker, se ele puder ser facilmente invadido por um hacker, vazando dados confidenciais dos usuários? 😱🔓",1788375146131]