🐳 ATIVIDADE 17: CONTAINERIZAÇÃO DE AMBIENTES COM DOCKER

📖 Fundamentação Teórica

Para realizar este laboratório com sucesso, certifique-se de ter compreendido os conceitos apresentados no:
👉 CAPÍTULO 17: ESTRATÉGIAS DE TESTE e CAPÍTULO 04 DE BANCO DE DADOS: SETUP COMPLETO

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! 🚀


🎯 Objetivos de Aprendizagem do Laboratório

Ao final deste laboratório prático (estimativa: 4 horas presenciais / autoguiadas), 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 Python 3.11+ com Flask 3.x.
  • Criar um arquivo docker-compose.yml para orquestrar múltiplos contêineres (App Flask + PostgreSQL 17) em rede local isolada.
  • Gerenciar redes virtuais privadas 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 Python, um usava SQLite local, outro usava PostgreSQL nativo do Windows na porta 5432, e um terceiro usava uma versão desatualizada de dependências que quebrava as migrações. A integração de novos programadores demorava até 3 dias apenas para configurar o ambiente 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 (Python 3.11, Flask 3.x e SQLAlchemy 2.0) e um arquivo docker-compose.yml que sobe, com um único comando, o servidor da aplicação e o banco de dados PostgreSQL 17 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 do requirements.txt, runtime do Python, 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 relacional, cache, app web) sobem prontas.

📊 Arquitetura do Ambiente Orquestrado com Docker

flowchart TD
    subgraph Host ["Máquina do Desenvolvedor (Host OS)"]
        direction TB
        subgraph DockerNet ["Rede Virtual Isolada (tecpro-network)"]
            direction LR
            App["Contêiner Web: Flask 3.x + SQLAlchemy 2.0"] <-->|Porta Interna 5432| DB[("Contêiner Database: PostgreSQL 17")]
        end
        PortApp["Porta Física Exposta: 5000"] <-->|Direciona Requisições HTTP| App
    end
    
    subgraph Persistencia ["Armazenamento Externo"]
        Volume[("Volume Docker: pgdata")] <---> DB
    end

    style Host fill:#f5f7fa,stroke:#333,stroke-width:2px
    style DockerNet fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
    style Persistencia fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
    style App fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
    style DB fill:#ffe0b2,stroke:#f57c00,stroke-width:2px

📖 Exemplo Guiado: Dockerização de Ponta a Ponta

Para empacotarmos a aplicação Flask 3.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 para definir a construção da imagem leve:

# Imagem base oficial leve do Python 3.11
FROM python:3.11-slim

# Evita a geração de arquivos .pyc e força flush imediato de logs
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

WORKDIR /app

# Copia dependências e instala sem cache para manter a imagem enxuta
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copia código-fonte da aplicação
COPY . .

# Expõe a porta padrão do Flask
EXPOSE 5000

# Comando para iniciar o servidor web
CMD ["python", "main.py"]

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:

services:
  # Serviço 1: Banco de Dados PostgreSQL 17
  database:
    image: postgres:17-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
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U tecpro_admin -d tecproexpress"]
      interval: 5s
      timeout: 5s
      retries: 5

  # Serviço 2: Aplicação Web Flask 3.x
  web-app:
    build: .
    container_name: tecpro-web-app
    restart: always
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgresql+psycopg2://tecpro_admin:SenhaSuperSegura123@database:5432/tecproexpress
    depends_on:
      database:
        condition: service_healthy
    networks:
      - tecpro-network

# Definição dos Recursos Compartilhados
volumes:
  pgdata:
    driver: local

networks:
  tecpro-network:
    driver: bridge

💻 Execução do Docker Compose & Logs no Terminal

Para subir todo o ecossistema (Aplicação Web + Banco de Dados PostgreSQL) com um único comando:

# Subir os contêineres e compilar a imagem em segundo plano
docker compose up -d --build

# Inspecionar o status dos serviços em execução
docker compose ps

🖥️ Saída Esperada no Terminal:

[+] Building 3.2s (8/8) FINISHED
[+] Running 3/3
 ✔ Network tecpro-network     Created                                      0.1s
 ✔ Container tecpro-db        Started                                      0.4s
 ✔ Container tecpro-web-app   Started                                      0.8s

NAME                IMAGE                 COMMAND                  SERVICE    STATUS     PORTS
tecpro-db           postgres:17-alpine    "docker-entrypoint.s…"   database   running    0.0.0.0:5432->5432/tcp
tecpro-web-app      tecproexpress-web-app "python main.py"         web-app    running    0.0.0.0:5000->5000/tcp

🛠️ 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 postgresql+psycopg2://tecpro_admin:SenhaSuperSegura123@database:5432/tecproexpress em vez de localhost:5432. 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 Técnicas:

  1. O Docker possui um servidor DNS interno embutido em suas redes do tipo bridge que resolve automaticamente o nome do serviço do Compose — no caso, database — diretamente para o endereço IP virtual interno do contêiner do Postgres.
  2. Graças à declaração do volume pgdata mapeado para o diretório /var/lib/postgresql/data, os dados bancários permanecem armazenados de forma persistente no sistema hospedeiro, não se perdendo mesmo quando o contêiner é totalmente destruído e recriado com docker compose down. 🐳💾🧠
---

📊 Rubrica Formativa de Avaliação

Critério de Avaliação Insuficiente (0% - 40%) Regular (41% - 70%) Excelente (71% - 100%)
Containerização com Dockerfile Dockerfile com sintaxe incorreta ou gerando imagens pesadas sem isolamento. Escreve o Dockerfile mas esquece flags de otimização (`--no-cache-dir`, variáveis de ambiente). Dockerfile impecável utilizando `python:3.11-slim`, variáveis `PYTHONDONTWRITEBYTECODE=1` e sem acúmulo de cache no pip.
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` com `healthcheck`), DNS do Docker e volume persistente `pgdata`.
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.