Docker - O Que É, Para Que Serve e Conceitos Iniciais
O Problema que o Docker Resolve "Na minha máquina funciona." Poucas frases resumem tão bem um problema que atormentou (e ainda atormenta) times de desenvolvimento: um código que roda perfeitamente no notebook do desenvolvedor, mas quebra no servidor de produção - porque a versão do Python é outra, uma biblioteca do sistema está faltando, uma variável de ambiente não foi configurada, ou o sistema operacional simplesmente se comporta de forma diferente. O Docker resolve exatamente isso: ele empacota uma aplicação junto com tudo que ela precisa para rodar - código, dependências, bibliotecas do sistema, variáveis de ambiente, configuração - em uma unidade isolada e portátil chamada container. Essa unidade roda da mesma forma em qualquer lugar que tenha o Docker instalado: no notebook do desenvolvedor, no servidor de CI, ou em produção. Esta é a primeira parte de uma série que vai do zero ao avançado em Docker: hoje o foco é entender o problema que ele resolve, os conceitos fundamentais e como eles se encaixam. 2. Containers vs Máquinas Virtuais A comparação mais comum ao explicar Docker é com máquinas virtuais (VMs), porque ambos resolvem um problema parecido - isolar e empacotar aplicações - mas de formas muito diferentes. Uma máquina virtual virtualiza o hardware inteiro: cada VM roda seu próprio sistema operacional completo (kernel incluso), gerenciado por um hypervisor. Isso garante isolamento forte, mas tem um custo alto: cada VM consome centenas de MBs a alguns GBs de disco e memória só para o SO, e leva de dezenas de segundos a minutos para inicializar. Um container, por outro lado, virtualiza no nível do sistema operacional: todos os containers em uma máquina compartilham o mesmo kernel do host, mas cada um enxerga seu próprio sistema de arquivos, processos e rede isolados - usando recursos do kernel Linux como namespaces (isolamento de visão) e cgroups (limites de CPU/memória). O resultado é que containers são muito mais leves: alguns MBs a poucas centenas de MBs, com inicialização em milissegundos a poucos segundos. ┌─────────────────────────┐ ┌─────────────────────────┐ │ VM 1 │ VM 2 │ │ Container 1│Container 2│ │ ┌─────┐ │ ┌─────┐ │ │ ┌───────┐ │ ┌───────┐ │ │ │ App │ │ │ App │ │ │ │ App │ │ │ App │ │ │ ├─────┤ │ ├─────┤ │ │ ├───────┤ │ ├───────┤ │ │ │ SO │ │ │ SO │ │ │ │ Libs │ │ │ Libs │ │ │ └─────┘ │ └─────┘ │ │ └───────┘ │ └───────┘ │ ├───────────┴──────────────┤ ├─────────────┴───────────┤ │ Hypervisor │ │ Docker Engine │ ├───────────────────────────┤ ├───────────────────────────┤ │ SO Host + Hardware │ │ SO Host + Hardware │ └───────────────────────────┘ └───────────────────────────┘ Isso não significa que containers substituem VMs em todo cenário - VMs continuam sendo a escolha certa quando o isolamento precisa ser total (por exemplo, rodar cargas de múltiplos clientes não confiáveis na mesma máquina física) ou quando se precisa de um kernel diferente do host. Mas para o caso mais comum - empacotar e distribuir aplicações de forma consistente - containers ganham em leveza, velocidade de inicialização e densidade (quantas cargas cabem na mesma máquina). 3. Os Três Conceitos Fundamentais: Imagens, Containers e Registries Todo o modelo mental do Docker gira em torno de três peças: - Imagem (image): um pacote read-only com tudo que uma aplicação precisa para rodar - sistema de arquivos, binários, bibliotecas, código da aplicação e metadados (como qual comando executar ao iniciar). É construída a partir de um Dockerfile (assunto do Artigo 3 desta série) e organizada em camadas (layers) empilhadas, o que permite reaproveitar partes já construídas entre builds diferentes. - Container: uma instância em execução de uma imagem. Se a imagem é a "planta" (como uma classe em programação orientada a objetos), o container é o "objeto" instanciado a partir dela - com um processo rodando, um sistema de arquivos gravável em cima da imagem read-only, e seu próprio espaço de rede isolado. É possível rodar múltiplos containers a partir da mesma imagem, cada um independente dos outros. - Registry: um repositório para armazenar e distribuir imagens. O Docker Hub é o registry público padrão (onde vivem imagens oficiais como python ,postgres ,nginx ), mas existem registries privados (AWS ECR, Google Artifact Registry, GitHub Container Registry) para imagens internas de uma empresa. O fluxo típico conecta essas três peças: escreve-se um Dockerfile , constrói-se uma imagem a partir dele, essa imagem é enviada (push ) para um registry, e em qualquer máquina com Docker instalado é possível baixá-la (pull ) e rodar um ou mais containers a partir dela. Dockerfile → (build) → Imagem → (push) → Registry │ (pull) │ ▼ Imagem local → (run) → Container 4. Instalando o Docker O Docker está disponível para Linux, macOS e Windows. Em distribuições Linux, o pacote oficial (não o docker.io genérico de alguns repositórios, que costuma ficar desatualizado) é instalado assim: # Debian/Ubuntu - script oficial de conveniência curl -fsSL https://get.docker.com | sh # Depois, para rodar docker sem sudo (requer novo login/logout): sudo usermod -aG docker $USER Em macOS e Windows, a forma mais comum é instalar o Docker Desktop, que empacota o engine, uma VM Linux leve (necessária porque o Docker depende de recursos do kernel Linux) e uma interface gráfica. Depois de instalado, confirme que está funcionando: docker --version docker run hello-world O segundo comando baixa uma imagem mínima do Docker Hub, roda um container a partir dela (que imprime uma mensagem de confirmação e termina) - é o "hello world" oficial do ecossistema Docker, útil para validar que o engine está rodando e tem permissão para baixar imagens. 5. Um Primeiro Container na Prática Para sair da teoria, um exemplo real: rodar um servidor web Nginx sem instalar nada além do Docker na máquina. docker run -d -p 8080:80 --name meu-nginx nginx Decompondo o comando: - docker run - cria e inicia um container a partir de uma imagem. - -d (detached) - roda o container em segundo plano, devolvendo o terminal imediatamente. - -p 8080:80 - mapeia a porta 8080 da máquina host para a porta 80 dentro do container (onde o Nginx escuta por padrão). - --name meu-nginx - dá um nome fácil de referenciar ao container, em vez de um id gerado automaticamente. - nginx - a imagem a usar. Como não existe localmente ainda, o Docker automaticamente fazpull dela do Docker Hub antes de rodar. Acessar http://localhost:8080 no navegador já mostra a página padrão do Nginx. Para conferir que o container está rodando e depois removê-lo: docker ps # lista containers em execução docker stop meu-nginx # para o container docker rm meu-nginx # remove o container (já parado) Note que docker stop e docker rm são passos separados - parar um container não o remove, apenas encerra o processo dentro dele. Isso é proposital: permite inspecionar o estado final de um container que falhou antes de descartá-lo. Os comandos do dia a dia como esses (run , exec , logs , ps , build ) são o assunto completo do próximo artigo. 6. Conclusão e Próximos Passos Nesta primeira parte, vimos o problema real que o Docker resolve ("funciona na minha máquina"), como containers se diferenciam de máquinas virtuais em leveza e velocidade, os três conceitos que sustentam todo o ecossistema - imagens, containers e registries - e rodamos o primeiro container de ponta a ponta. No próximo artigo, o foco vai para os comandos que realmente viram hábito no dia a dia: run , exec , logs , ps e build , com exemplos de containers reais além do "hello world". Imagem de capa: Logo oficial do Docker - Wikimedia Commons, fonte: docker.com/company/newsroom/media-resources Referências: Top comments (0)
Comments
No comments yet. Start the discussion.