Docker para iniciantes: containers na prática
Guia prático de Docker para quem está começando: o que são containers, como criar uma imagem e os comandos do dia a dia.
Neste artigo
Todo desenvolvedor já passou pela frase 'na minha máquina funciona'. O Docker nasceu justamente para acabar com esse problema, empacotando uma aplicação junto com tudo que ela precisa para rodar — bibliotecas, dependências, variáveis de ambiente — em uma unidade isolada e portátil chamada container. Em 2026, saber operar containers deixou de ser diferencial e virou pré-requisito básico para qualquer pessoa que escreve ou entrega software.
Imagem e container não são a mesma coisa#
A imagem é o molde: um conjunto de camadas somente leitura que descreve o sistema de arquivos e as instruções para rodar a aplicação. O container é a instância em execução dessa imagem, com uma camada gravável por cima. É possível criar dezenas de containers a partir da mesma imagem, cada um isolado dos outros, mas todos compartilhando o kernel do sistema operacional hospedeiro — diferente de uma máquina virtual, que precisa emular um sistema operacional inteiro.
O Dockerfile: a receita da imagem#
Um Dockerfile é um arquivo de texto com instruções sequenciais: qual imagem base usar, quais arquivos copiar, quais comandos rodar durante a construção e qual comando executar quando o container subir. Cada instrução gera uma camada, e o Docker reaproveita camadas não alteradas em builds futuros, o que acelera bastante o ciclo de desenvolvimento. Boas práticas incluem usar imagens base enxutas, copiar apenas o necessário e nunca embutir segredos diretamente no arquivo.
Comandos essenciais do dia a dia#
O fluxo básico envolve construir a imagem, rodar o container e inspecionar o que está acontecendo. Comandos como build para gerar a imagem, run para subir um container, ps para listar containers ativos, logs para ver a saída da aplicação e exec para abrir um terminal dentro de um container em execução cobrem a maior parte do trabalho diário. Entender essas ferramentas evita depender de memória e permite diagnosticar problemas com rapidez em produção.
Volumes, redes e o compose#
Containers são efêmeros por natureza: quando removidos, tudo que foi gravado na camada gravável some junto. Volumes resolvem isso, persistindo dados fora do ciclo de vida do container. Redes permitem que containers se comuniquem entre si por nome, sem depender de IPs fixos. Quando um projeto envolve múltiplos serviços — API, banco, cache — o Docker Compose descreve toda essa topologia em um único arquivo declarativo, facilitando subir o ambiente inteiro com um comando.
Erros comuns de quem está começando#
Rodar containers como root sem necessidade, ignorar o tamanho da imagem final e misturar dependências de build com dependências de execução são armadilhas frequentes. Builds multi-estágio resolvem o último ponto: uma etapa compila a aplicação, outra copia apenas o artefato final para uma imagem mínima, deixando o resultado menor e com superfície de ataque reduzida.
Healthchecks e políticas de reinício#
Healthchecks e políticas de reinício também merecem atenção assim que o container sai do ambiente de desenvolvimento. Declarar um healthcheck no Dockerfile ou no compose permite que o orquestrador saiba quando o processo interno está realmente pronto para receber tráfego, não apenas quando o processo iniciou. Combinado com uma política de restart adequada, isso evita que um container travado continue recebendo requisições silenciosamente, um problema comum em produção quando ninguém está observando os logs em tempo real.
Gestão de tags de imagem e rastreabilidade#
Outro ponto que passa despercebido no início é a gestão de tags de imagem. Usar sempre a tag latest parece prático, mas torna impossível saber com certeza qual versão do código está rodando em cada ambiente, além de dificultar um rollback rápido em caso de problema. Tags baseadas no hash do commit ou em versionamento semântico, combinadas com um registro de imagens privado, dão rastreabilidade real sobre o que foi implantado e quando, o que faz toda diferença na hora de investigar um incidente.
Limites de recursos e isolamento entre containers#
Limites explícitos de CPU e memória por container também fazem parte de uma configuração madura, evitando que um único processo com vazamento de memória ou loop descontrolado derrube a máquina inteira e afete outros serviços vizinhos rodando no mesmo host. Definir esses limites desde o ambiente de desenvolvimento, e não só em produção, ajuda o time a perceber cedo quando uma aplicação está consumindo recursos além do esperado, antes que isso vire um incidente real.
Segurança de imagem: escaneamento e base mínima#
Toda imagem baixada de um registro público carrega o risco de conter vulnerabilidades conhecidas nas suas camadas de sistema operacional e bibliotecas base, mesmo que o código da própria aplicação esteja perfeito. Escanear imagens automaticamente antes de publicá-las em um registro interno, e preferir imagens base minimalistas com o menor número possível de pacotes instalados, reduz consideravelmente essa superfície de ataque herdada. Reconstruir e reescanear imagens regularmente, mesmo sem nenhuma mudança no código da aplicação, também é necessário, já que novas vulnerabilidades em pacotes do sistema operacional são descobertas continuamente depois que a imagem original foi publicada.
Registries: onde as imagens vivem#
Um registro de imagens é o repositório central onde imagens construídas são armazenadas e distribuídas, análogo a um repositório de código-fonte, mas para artefatos de container prontos para execução. Registros públicos hospedam imagens abertas mantidas pela comunidade, enquanto registros privados guardam imagens proprietárias de uma organização, geralmente integrados ao pipeline de integração contínua, que publica automaticamente uma nova versão da imagem a cada mudança aprovada no código. Controlar quem pode publicar e quem pode consumir imagens de um registro privado é parte importante da segurança da cadeia de suprimentos de software, evitando que uma imagem maliciosa se infiltre no processo de build.
Diferença entre Docker e máquina virtual#
A confusão entre container e máquina virtual é comum entre quem está começando, mas a diferença é fundamental: uma máquina virtual emula hardware completo e roda um sistema operacional inteiro próprio, com overhead significativo de memória e tempo de inicialização medido em minutos. Um container compartilha o kernel do sistema operacional hospedeiro, isolando apenas processos, sistema de arquivos e rede, o que resulta em inicialização em segundos e consumo de recursos muito menor. Essa leveza é o que torna viável rodar dezenas de containers na mesma máquina onde só uma ou duas máquinas virtuais caberiam confortavelmente.
Persistência de dados e bancos de dados em container#
Rodar um banco de dados dentro de um container é uma prática comum em desenvolvimento e cada vez mais aceita em produção, desde que os dados sejam persistidos corretamente em um volume externo ao ciclo de vida do container, e não na camada gravável efêmera padrão. Backups regulares desse volume continuam sendo obrigatórios, já que containerizar o banco não elimina a necessidade de uma estratégia de recuperação de desastre — pelo contrário, facilita testar essa estratégia com mais frequência, já que recriar um ambiente completo de teste a partir de uma imagem e um backup de volume se torna um processo rápido e reproduzível.
Rede entre containers: bridge, host e overlay#
O Docker oferece diferentes drivers de rede para cenários distintos. O modo bridge, padrão em uma máquina única, cria uma rede virtual isolada onde containers se enxergam por nome e o host controla o roteamento de portas expostas para fora. O modo host remove esse isolamento de rede, fazendo o container compartilhar diretamente a pilha de rede da máquina hospedeira, útil em cenários de performance extrema mas com isolamento de segurança reduzido. Redes overlay entram em cena em clusters com múltiplas máquinas, permitindo que containers rodando em hosts físicos diferentes se comuniquem como se estivessem na mesma rede local, uma peça fundamental para qualquer sistema de orquestração distribuído.
Perguntas frequentes sobre Docker#
É seguro rodar containers em produção sem nenhuma orquestração? Para uma aplicação única e simples, sim, mas a ausência de reinício automático coordenado, balanceamento de carga entre réplicas e recuperação diante da falha de uma máquina inteira limita bastante a resiliência do sistema à medida que ele cresce. Docker substitui completamente a necessidade de configurar servidores? Não — o container ainda roda sobre um sistema operacional hospedeiro que precisa ser mantido, atualizado e protegido, o Docker apenas isola e padroniza o que roda dentro dele.
Docker Desktop e ambientes de desenvolvimento locais#
Para desenvolvedores em máquinas locais, ferramentas como Docker Desktop simplificam a instalação e o gerenciamento visual de containers, imagens e volumes, abstraindo boa parte da complexidade de configurar o daemon do Docker manualmente em cada sistema operacional. Times que padronizam o ambiente de desenvolvimento inteiro em containers — banco de dados, cache, serviços auxiliares — conseguem onboarding de novos integrantes em minutos em vez de dias, já que o passo a passo de 'instalar isso, configurar aquilo' dá lugar a um único comando que sobe o ambiente completo já configurado e pronto para uso imediato.
Docker em orquestração: o próximo passo natural#
Boas práticas de Dockerfile em uma lista rápida#
Algumas práticas consolidadas fazem diferença consistente na qualidade de uma imagem: ordenar instruções do Dockerfile das que mudam menos para as que mudam mais, aproveitando melhor o cache de camadas; usar um arquivo de exclusão para não copiar arquivos desnecessários, como a pasta de controle de versão, para dentro da imagem; fixar versões exatas de dependências em vez de usar sempre a versão mais recente disponível, garantindo builds reproduzíveis; e nunca copiar arquivos de configuração com segredos reais para dentro da imagem, injetando esses valores em tempo de execução através de variáveis de ambiente ou de um gerenciador de segredos dedicado.
Dominar Docker não significa decorar todos os comandos, mas entender o modelo mental por trás de imagens, camadas e isolamento. A partir daí, ferramentas de orquestração maiores, como Kubernetes, deixam de parecer mágica e passam a fazer sentido como uma extensão natural desses mesmos conceitos: em vez de gerenciar containers manualmente em uma única máquina, o orquestrador decide em qual servidor de um cluster cada container deve rodar, reinicia automaticamente o que falha e distribui tráfego entre múltiplas réplicas do mesmo serviço.