🐳 Atividade 17: Containerização de Ambientes com Docker
Hoje, aprenderemos sobre Docker e 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! 🚀
🎯 Objetivo da Aula
Ao final desta atividade, você será capaz de:
- Compreender os conceitos fundamentais de Contêineres vs Máquinas Virtuais.
- Escrever um Dockerfile otimizado para empacotar uma aplicação web Java 17 com Spring Boot.
- Criar um arquivo docker-compose.yml para orquestrar múltiplos contêineres (App + PostgreSQL) em rede local isolada.
- Gerenciar redes virtuais e volumes persistentes no ambiente Docker.
🏢 O Cenário Prático (Seu Desafio)
Na 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!
"Seu desafio como Arquiteto de Soluções é padronizar e automatizar 100% do ambiente da TecProExpress. Você criará o arquivo
Dockerfileda aplicação web (Java 17, Spring Boot, Thymeleaf e HTMX) e um arquivodocker-compose.ymlque 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."
🧠 Fundamentos: A Teoria Traduzida
- 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).
- 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.
- Dockerfile: O script com comandos sequenciais para construir a Imagem do contêiner.
- Docker Compose: A ferramenta que permite definir e rodar aplicações multi-contêiner. Com um único comando (
docker-compose up), todas as dependências (banco, cache, app) sobem prontas.
📊 Arquitetura do Ambiente Orquestrado com Docker
📖 Exemplo Guiado: Dockerização de Ponta a Ponta
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.
1. 🛠️ O Arquivo Dockerfile da Aplicação
Criamos um arquivo com o nome exato Dockerfile (sem extensão) na raiz do projeto Java para definir a construção da nossa imagem:
# Etapa 1: Construção (Build) utilizando o Maven oficial com Java 17
FROM maven:3.8.8-eclipse-temurin-17 AS builder
WORKDIR /app
# Copia os arquivos de configuração do Maven e o código fonte
COPY pom.xml .
COPY src ./src
# Compila o projeto e gera o arquivo JAR executável ignorando os testes (já rodados no CI)
RUN mvn clean package -DskipTests
# Etapa 2: Execução (Runtime) com imagem leve JRE
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# Copia o JAR compilado da primeira etapa para o ambiente final
COPY --from=builder /app/target/*.jar app.jar
# Expõe a porta padrão do Spring Boot
EXPOSE 8080
# Variáveis de ambiente padrão (podem ser sobrescritas pelo Compose)
ENV SPRING_PROFILES_ACTIVE=prod
# Comando para iniciar a aplicação
ENTRYPOINT ["java", "-jar", "app.jar"]
2. 📄 O Arquivo docker-compose.yml de Orquestração
Na mesma raiz do projeto, criamos o arquivo docker-compose.yml para conectar a nossa aplicação ao banco de dados PostgreSQL de forma indestrutível:
version: '3.8'
services:
# Serviço 1: Banco de Dados PostgreSQL
database:
image: postgres:15-alpine
container_name: tecpro-db
restart: always
environment:
POSTGRES_DB: tecproexpress
POSTGRES_USER: tecpro_admin
POSTGRES_PASSWORD: SenhaSuperSegura123
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- tecpro-network
# Serviço 2: Aplicação Java Spring Boot
web-app:
build: .
container_name: tecpro-web-app
restart: always
ports:
- "8080:8080"
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://database:5432/tecproexpress
- SPRING_DATASOURCE_USERNAME=tecpro_admin
- SPRING_DATASOURCE_PASSWORD=SenhaSuperSegura123
- SPRING_JPA_DATABASE-PLATFORM=org.hibernate.dialect.PostgreSQLDialect
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
depends_on:
- database
networks:
- tecpro-network
# Definição dos Recursos Compartilhados
volumes:
pgdata:
driver: local
networks:
tecpro-network:
driver: bridge
🛠️ Prática Obrigatória 1: Desenho da Rede de Contêineres
Cenário: Mapeamento conceitual do ecossistema de contêineres e fluxo de comunicação.
- Desenhe um diagrama
flowchartno Mermaid representando a arquitetura dos contêineres da sua aplicação. - 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.
- Evidencie a comunicação interna entre a aplicação e o banco PostgreSQL utilizando a rede virtualizada privada.
🏁 Resultado Esperado (Para sua Referência)
Um diagrama visual nítido exibindo o redirecionamento de portas (port-forwarding), volumes de persistência e a barreira da rede virtual.
🛠️ Prática Obrigatória 2: Criando os Arquivos de Configuração
Cenário: Escrevendo os scripts de containerização para o seu projeto semestral.
- Escreva o script
Dockerfilepersonalizado para o seu sistema de grupo, adaptando caso seu ecossistema necessite de variáveis ou passos específicos. - Escreva o arquivo
docker-compose.ymlque orquestra a aplicação de vocês integrada com um banco de dados persistido e mapeamento de portas do host para o contêiner.
📤 Instruções de Entrega (Microsoft Teams)
Após projetar a sua infraestrutura containerizada:
- Salve o arquivo de especificações e códigos com o nome
Atividade_17.mdna pastaes-atv-17-conteineres-docker/do seu repositório GitHub. - Certifique-se de fazer o commit e push para o repositório público.
- Submeta o link do seu repositório no Microsoft Teams para avaliação do professor.
💡 Checkpoint de Lógica
docker-compose.yml, a URL de conexão do banco de dados na aplicação web foi definida como jdbc:postgresql://database:5432/tecproexpress em vez de jdbc:postgresql://localhost:5432/tecproexpress. Por que a palavra 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 volumes? (Respostas: O Docker possui um DNS embutido em suas redes virtuais que resolve o nome do serviço do Compose — no caso, database — diretamente para o IP interno dinâmico do contêiner do Postgres. Graças à declaração do volume 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). 🐳💾🧠📊 Rubrica Formativa de Avaliação
| Critério de Avaliação | Insuficiente (0% - 40%) | Regular (41% - 70%) | Excelente (71% - 100%) |
|---|---|---|---|
| Containerização & Multi-stage Build (Dockerfile) | Dockerfile com sintaxe incorreta ou gerando imagens pesadas sem isolamento de build. | Escreve o Dockerfile mas sem utilizar a técnica de Multi-stage build. | Dockerfile impecável utilizando Multi-stage Build (compilação leve com Maven/JDK e runtime enxuto JRE Alpine). |
| Orquestração Multi-serviço (Docker Compose) | Erros na sintaxe YAML do `docker-compose.yml` ou ausência de mapeamento de portas e volumes. | Orquestra a aplicação e o banco mas esquece da persistência em `volumes`. | Compose perfeito com serviços orquestrados (`depends_on`), variáveis de ambiente atreladas ao DNS do Docker e volume persistente de banco. |
| Entrega no GitHub | Entrega fora da pasta `es-atv-17-conteineres-docker/`. | Arquivo entregue sem a explicação da rede virtual do Compose. | Submete `Atividade_17.md` contendo Dockerfile, Compose YAML e diagrama Mermaid de portas/redes formatados. |
🚀 Atividade 16: Pipelines de CI/CD com GitHub Actions
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! 🛡️🧩
🔒 Atividade 18: Segurança no Desenvolvimento e OWASP
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/CD verde e rodando em Docker, se ele puder ser facilmente invadido por um hacker, vazando dados confidenciais dos usuários? 😱🔓