🛠️ Atividades

🐳 Atividade 17: Containerização de Ambientes com Docker

Bem-vindo a mais uma etapa prática da sua jornada na Engenharia de Software! Após automatizarmos nossos testes no pipeline de CI/CD, 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?" 🤦‍♂️💻

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 Dockerfile da aplicação web (Java 17, Spring Boot, Thymeleaf e HTMX) e um arquivo docker-compose.yml 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."


🧠 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.

  1. Desenhe um diagrama flowchart no Mermaid representando a arquitetura dos contêineres da sua aplicação.
  2. 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.
  3. 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.

  1. Escreva o script Dockerfile personalizado para o seu sistema de grupo, adaptando caso seu ecossistema necessite de variáveis ou passos específicos.
  2. Escreva o arquivo docker-compose.yml 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.

📤 Instruções de Entrega (Microsoft Teams)

Após projetar a sua infraestrutura containerizada:

  1. Salve o arquivo de especificações e códigos com o nome Atividade_17.md na pasta es-atv-17-conteineres-docker/ do seu repositório GitHub.
  2. Certifique-se de fazer o commit e push para o repositório público.
  3. Submeta o link do seu repositório no Microsoft Teams para avaliação do professor.

💡 Checkpoint de Lógica

Importante:Reflexão Profissional: No arquivo 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.
Copyright © 2026