Docker permite empacotar aplicações com todas as suas dependências, garantindo que rodem de forma consistente em qualquer ambiente.
🤔 O que são Containers?
Conceito
Containers são como “caixas” que encapsulam uma aplicação e todas as suas dependências (bibliotecas, configurações, etc.). Servem para garantir que uma aplicação seja executada de forma consistente em diferentes ambientes.
Resolve o problema: “Na minha máquina funciona!”
Não é máquina virtual!
Única missão de um container é fazer uma aplicação específica funcionar!
📊 Exemplo sem Container
📦 Exemplo com Container
⚖️ Docker x VMs
A diferença fundamental entre Docker e uma Máquina Virtual (VM) está em onde cada um roda. Uma VM emula hardware completo, incluindo um sistema operacional inteiro. Um container compartilha o kernel do host e isola apenas o processo da aplicação. O resultado é um container que inicia em milissegundos e ocupa megabytes, enquanto uma VM demora minutos e ocupa gigabytes.
flowchart LR
subgraph VM["Máquina Virtual"]
direction TB
HW["Hardware físico"]
HYP["Hypervisor (VMware/VirtualBox)"]
GOS1["SO Convidado (Linux completo)"]
GOS2["SO Convidado (Windows completo)"]
A1["App A"]
A2["App B"]
HW --> HYP --> GOS1 --> A1
HYP --> GOS2 --> A2
end
subgraph DC["Docker / Containers"]
direction TB
HW2["Hardware físico"]
OS["SO Host (Linux)"]
DE["Docker Engine"]
C1["Container A\n(só a App + libs)"]
C2["Container B\n(só a App + libs)"]
HW2 --> OS --> DE --> C1
DE --> C2
end
Por que containers são mais leves?
Containers não carregam um sistema operacional inteiro: reaproveitam o kernel do host. Uma imagem Ubuntu no Docker tem cerca de 29 MB; uma VM Ubuntu completa exige 2 GB ou mais.
📜 Surgimento do Docker
Década
Marco
1990s
Primeiras formas de isolamento de processos (chroot)
2000s
Surgimento de LXC (Linux Containers)
2013
Lançamento do Docker
Exemplo de chroot
O conceito de isolamento surgiu com o chroot, que permite alterar o diretório raiz de um processo:
# Cria um diretóriosudo mkdir -p /mycontainer# Copia binários essenciais e monta um sistemas de arquivossudo cp -R /bin /lib /lib64 /usr /mycontainer/sudo mkdir -p /mycontainer/{dev,proc,sys}sudo mount -t proc proc /mycontainer/procsudo mount -t sysfs sys /mycontainer/syssudo mount -o bind /dev /mycontainer/devsudo mount -t devpts devpts /mycontainer/dev/pts# Usa chroot para mudar a raiz do sistema, criando um ambiente isolado.sudo chroot /mycontainer /bin/bash
🐳 O que é Docker?
Definição
Docker é uma plataforma de virtualização de containers que permite empacotar, distribuir e executar aplicações de forma isolada e consistente. Diferente das máquinas virtuais tradicionais, containers Docker compartilham o kernel do sistema operacional host, tornando-os mais leves e eficientes.
📈 Docker no Mercado (2025-2026)
Os números mostram que Docker saiu de tecnologia de nicho para infraestrutura padrão da indústria:
Indicador
Valor (2025/2026)
Profissionais de TI que usam Docker
92% (era 80% em 2024)
Desenvolvedores profissionais com Docker
71% (alta de 17 pontos em 1 ano)
Participação no mercado de containerização
87%
Downloads mensais de containers no Docker Hub
13 bilhões
Tamanho do mercado (2026)
USD 7,4 bilhões
Crescimento anual projetado (CAGR)
21% ao ano até 2031
Por que esses números importam?
Docker não é mais uma “ferramenta opcional”. Em 2026, saber Docker é tão esperado de um profissional de TI quanto saber Git. Empresas contratam esperando que o candidato já saiba criar e gerenciar containers.
Novidades de 2025-2026:
Docker Hardened Images: mais de 1.000 imagens com segurança reforçada, gratuitas no Docker Hub
Docker Model Runner: suporte nativo a modelos de IA (como Qwen) rodando em containers locais
Docker MCP Toolkit: integração com servidores MCP para agentes de IA
Containers com namespace de tempo privado (isolamento ainda mais forte no Linux)
✨ Principais Benefícios
Benefício
Descrição
Isolamento
Cada container roda de forma isolada
Portabilidade
”Build once, run anywhere”
Eficiência
Mais leve que VMs tradicionais
Escalabilidade
Facilita múltiplas instâncias
🧩 Componentes Principais
Docker Engine
O mecanismo principal do Docker que cria e gerencia containers. É um daemon (processo em segundo plano) que responde a comandos via CLI ou API. Quando você digita docker run, é o Docker Engine que interpreta o comando, baixa a imagem necessária, cria o container e o executa.
O Docker Hub é o registro público oficial de imagens Docker:
Repositório oficial de imagens base e populares
Repositórios públicos e privados
Integração com sistemas de CI/CD
Controle de versões através de tags
Além do Docker Hub, existem outros registries: GitHub Container Registry (ghcr.io), Google Artifact Registry, Amazon ECR e registries privados auto-hospedados.
Dockerfile
Arquivo de Configuração
Arquivo de texto que contém todas as instruções para criar uma imagem Docker.
Contêm código, runtime, bibliotecas e configurações
Construídas em camadas (cada instrução cria uma nova camada)
O sistema de camadas traz uma vantagem enorme: reaproveitamento. Se dois projetos usam FROM python:3.11, as camadas base são baixadas e armazenadas uma única vez no disco. Só as camadas que diferem entre as duas imagens precisam de espaço extra.
Volumes
São espaços de armazenamento para persistir dados (como um HD virtual).
Por padrão, tudo que um container escreve no disco desaparece quando o container é removido. Volumes resolvem isso: os dados ficam no host e sobrevivem à exclusão do container. Isso é essencial para bancos de dados, uploads de usuários e qualquer dado que precise persistir.
# Criar um volume nomeadodocker volume create meus-dados# Usar o volume ao rodar o containerdocker run -v meus-dados:/app/data minha-imagem
Redes
Tipo
Descrição
bridge
Rede padrão para containers em um único host
host
Containers compartilham a rede do host
none
Desabilita a rede para o container
Containers na mesma rede bridge personalizada podem se comunicar pelo nome do container como hostname, sem precisar de endereço IP fixo. É assim que o Flask encontra o MySQL no exemplo da prática: o host de conexão é simplesmente db (nome do serviço no Compose).
🔄 Fluxo: Código para Container em Produção
O diagrama abaixo mostra o ciclo completo, do código do desenvolvedor até o container rodando em produção:
A imagem publicada no registry é exatamente a mesma que roda em DEV, STAGING e PRODUÇÃO. Não há surpresa de ambiente: o que funciona no seu notebook é o que vai para o servidor.
Objetivo: verificar que o Docker está funcionando e observar o ciclo completo de uma execução.
Passo 1: rode o container oficial de boas-vindas:
docker run hello-world
Resultado esperado: o Docker baixa a imagem hello-world do Docker Hub, cria um container, executa uma mensagem de confirmação e encerra. Você verá a linha Hello from Docker! no terminal.
Passo 2: suba um servidor web Nginx em segundo plano:
docker run -d -p 8080:80 --name meu-nginx nginx
Resultado esperado: o terminal devolve apenas o ID do container (nada trava). Abra o navegador em http://localhost:8080 e veja a página padrão do Nginx: Welcome to nginx!.
Passo 3: inspecione os containers ativos e todas as imagens baixadas:
docker ps -adocker images
Identifique na saída: o nome meu-nginx, o status Up, a porta 0.0.0.0:8080->80/tcp e as imagens hello-world e nginx listadas localmente.
Passo 4 (limpeza): pare e remova o container:
docker stop meu-nginxdocker rm meu-nginx
🧪 Atividade 2: Escreva e empacote sua própria aplicação
Objetivo: criar um Dockerfile do zero, construir uma imagem personalizada e rodar sua própria aplicação em container.
Passo 1: crie uma pasta para o projeto e entre nela:
mkdir meu-app && cd meu-app
Passo 2: crie o arquivo app.py com o conteúdo abaixo (aplicação Flask mínima):
from flask import Flaskapp = Flask(__name__)@app.route("/")def home(): return "<h1>Olá do meu container Docker!</h1>"if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)
Resultado esperado: o Docker executa cada instrução do Dockerfile em sequência e exibe Successfully built ao final.
Passo 6: rode o container mapeando a porta:
docker run -d -p 5000:5000 --name minha-app meu-app:v1
Abra http://localhost:5000 no navegador. Você verá: Olá do meu container Docker!
Passo 7: confirme que a imagem está listada localmente:
docker images
Localize meu-app com a tag v1 e o tamanho em MB.
🎼 Docker Compose
Orquestração Multi-Container
Docker Compose permite definir e executar múltiplos containers de forma declarativa através de um único arquivo YAML.
Quando uma aplicação cresce, ela passa a depender de vários serviços: banco de dados, cache, fila de mensagens, servidor web. Gerenciar cada container manualmente com docker run vira um pesadelo. O Compose resolve isso com um único arquivo docker-compose.yml que descreve todos os serviços, redes e volumes do projeto, e um único comando para subir tudo:
docker compose up -d
A diferença entre docker-compose (V1, Python, instalado separado) e docker compose (V2, Go, integrado ao Docker Engine) é que a V1 foi descontinuada. Em instalações modernas (Docker Engine 20.10+), use sempre docker compose sem hífen.
# Acessar o containerdocker exec -it mysql-container bash# Conectar ao MySQLmysql -u admin -p# Selecionar banco e listar dadosUSE flask-crud;SHOW TABLES;SELECT * FROM user;# SairEXIT;exit
Parte II: Dockerizando 100% do Projeto
1. Criar Dockerfile
# Usa uma imagem oficial do Python como baseFROM python:3.11# Define o diretório de trabalho dentro do contêinerWORKDIR /app# Copia os arquivos do projeto para o contêinerCOPY . .# Instala as dependênciasRUN pip install --no-cache-dir -r requirements.txt# Define a variável de ambiente para evitar buffer no outputENV PYTHONUNBUFFERED=1# Expõe a porta 5000EXPOSE 5000# Comando para rodar a aplicaçãoCMD ["python", "app.py"]