Docker para Iniciantes: ContĂȘineres Simplificados
· 12 min de leitura
Ăndice
- O Que Ă Docker?
- ContĂȘineres vs MĂĄquinas Virtuais
- Conceitos Fundamentais do Docker
- Comandos Essenciais do Docker
- Escrevendo Dockerfiles
- Docker Compose para AplicaçÔes Multi-ContĂȘiner
- Redes e Volumes do Docker
- Melhores PrĂĄticas do Docker
- Armadilhas Comuns e Como EvitĂĄ-las
- Casos de Uso do Mundo Real
- Perguntas Frequentes
- Artigos Relacionados
O Que Ă Docker?
Docker Ă© uma plataforma que permite empacotar aplicaçÔes e suas dependĂȘncias em contĂȘineres leves e portĂĄteis. Pense em um contĂȘiner como uma pequena caixa autossuficiente que contĂ©m tudo o que sua aplicação precisa para executar: cĂłdigo, runtime, bibliotecas e ferramentas do sistema. Chega de problemas do tipo "funciona na minha mĂĄquina".
Antes do Docker, implantar software significava instalar dependĂȘncias manualmente, configurar servidores e torcer para que nada entrasse em conflito. VocĂȘ gastaria horas configurando versĂ”es do Python, pacotes do Node.js, drivers de banco de dados e bibliotecas do sistema. Depois faria tudo de novo nos servidores de staging e produção, rezando para que as configuraçÔes correspondessem.
O Docker elimina esse caos garantindo que sua aplicação execute de forma idĂȘntica em qualquer lugar â seu laptop, a mĂĄquina de um colega, servidores de staging ou produção. O contĂȘiner se torna a unidade de implantação, nĂŁo apenas o cĂłdigo da aplicação.
O Docker se tornou a ferramenta padrĂŁo para desenvolvimento de software moderno. Seja construindo microsserviços, configurando pipelines de CI/CD ou apenas querendo um ambiente de desenvolvimento consistente, o Docker torna isso possĂvel com sobrecarga mĂnima. Empresas como Netflix, Spotify e PayPal executam milhĂ”es de contĂȘineres em produção todos os dias.
Dica rĂĄpida: Docker nĂŁo Ă© apenas para implantaçÔes em produção. Muitos desenvolvedores o usam para evitar poluir sua mĂĄquina local com diferentes versĂ”es de linguagens, bancos de dados e ferramentas. Precisa de PostgreSQL para um projeto e MySQL para outro? Execute ambos em contĂȘineres sem conflitos.
ContĂȘineres vs MĂĄquinas Virtuais
ContĂȘineres e mĂĄquinas virtuais fornecem isolamento, mas funcionam de maneira muito diferente internamente. Entender essa diferença Ă© crucial para apreciar por que os contĂȘineres se tornaram tĂŁo populares.
MĂĄquinas Virtuais executam um sistema operacional completo com seu prĂłprio kernel sobre um hypervisor. Cada VM precisa de sua prĂłpria instalação de SO, consumindo gigabytes de espaço em disco e memĂłria significativa. Os tempos de inicialização sĂŁo medidos em minutos. Se vocĂȘ executar trĂȘs VMs, estarĂĄ executando trĂȘs sistemas operacionais completos simultaneamente.
ContĂȘineres compartilham o kernel do SO host e apenas empacotam a camada de aplicação. Eles tĂȘm megabytes de tamanho (nĂŁo gigabytes), iniciam em segundos (nĂŁo minutos), e vocĂȘ pode executar dezenas em uma Ășnica mĂĄquina sem problemas.
# Abordagem VM: Cada aplicação recebe um SO completo
App A â SO Convidado â Hypervisor â SO Host â Hardware
App B â SO Convidado â Hypervisor â SO Host â Hardware
# Abordagem ContĂȘiner: AplicaçÔes compartilham o kernel
App A â Runtime de ContĂȘiner â SO Host â Hardware
App B â Runtime de ContĂȘiner â SO Host â Hardware
Essa arquitetura leve torna os contĂȘineres ideais para microsserviços, onde vocĂȘ pode executar centenas de pequenos serviços em vez de uma aplicação monolĂtica. A eficiĂȘncia de recursos Ă© impressionante â um servidor que executa 10 VMs pode executar confortavelmente 100 contĂȘineres.
| Recurso | MĂĄquinas Virtuais | ContĂȘineres |
|---|---|---|
| Tempo de Inicialização | Minutos | Segundos |
| Espaço em Disco | Gigabytes (SO completo) | Megabytes (apenas camada de aplicação) |
| Desempenho | PrĂłximo ao nativo | Nativo (sem sobrecarga de hypervisor) |
| Isolamento | Completo (kernel separado) | NĂvel de processo (kernel compartilhado) |
| Portabilidade | Limitada (dependente de hypervisor) | Alta (executa onde o Docker executa) |
| Uso de Recursos | Pesado | Leve |
Dito isso, as VMs nĂŁo estĂŁo obsoletas. Elas fornecem isolamento mais forte, pois cada VM tem seu prĂłprio kernel. Para cargas de trabalho crĂticas de segurança ou quando vocĂȘ precisa executar diferentes sistemas operacionais, as VMs continuam sendo a melhor escolha. Muitas organizaçÔes usam ambas: VMs para isolamento de infraestrutura e contĂȘineres para implantação de aplicaçÔes.
Conceitos Fundamentais do Docker
O Docker tem alguns conceitos-chave que vocĂȘ precisa entender antes de mergulhar em comandos e Dockerfiles. Esses blocos de construção formam a base de como o Docker funciona.
Imagens
Uma imagem Docker Ă© um modelo somente leitura contendo o cĂłdigo da sua aplicação, runtime, bibliotecas e dependĂȘncias. Pense nela como um snapshot ou blueprint. As imagens sĂŁo construĂdas a partir de instruçÔes em um Dockerfile e armazenadas em registros como o Docker Hub.
As imagens sĂŁo compostas de camadas. Cada instrução em um Dockerfile cria uma nova camada. O Docker armazena essas camadas em cache, entĂŁo se vocĂȘ reconstruir uma imagem e apenas a Ășltima camada mudou, o Docker reutiliza as camadas em cache. Isso torna as construçÔes incrivelmente rĂĄpidas.
ContĂȘineres
Um contĂȘiner Ă© uma instĂąncia em execução de uma imagem. VocĂȘ pode criar mĂșltiplos contĂȘineres a partir da mesma imagem, e cada um executa isoladamente. Quando vocĂȘ para um contĂȘiner, quaisquer alteraçÔes feitas dentro dele sĂŁo perdidas, a menos que vocĂȘ as salve explicitamente ou use volumes.
Os contĂȘineres sĂŁo efĂȘmeros por design. Essa imutabilidade Ă© um recurso, nĂŁo um bug â garante consistĂȘncia e torna o escalonamento trivial.
Dockerfile
Um Dockerfile Ă© um arquivo de texto contendo instruçÔes para construir uma imagem Docker. Ele especifica a imagem base, copia seu cĂłdigo, instala dependĂȘncias e define como executar sua aplicação. Vamos nos aprofundar em Dockerfiles em uma seção posterior.
Registro Docker
Um registro Ă© um sistema de armazenamento e distribuição para imagens Docker. O Docker Hub Ă© o registro pĂșblico padrĂŁo, hospedando milhĂ”es de imagens. VocĂȘ tambĂ©m pode executar registros privados para aplicaçÔes proprietĂĄrias. Quando vocĂȘ executa docker pull nginx, o Docker baixa a imagem nginx do Docker Hub.
Volumes
Volumes sĂŁo o mecanismo do Docker para persistir dados. Como os contĂȘineres sĂŁo efĂȘmeros, quaisquer dados gravados dentro de um contĂȘiner desaparecem quando ele para. Os volumes permitem armazenar dados fora do sistema de arquivos do contĂȘiner, sobrevivendo a reinicializaçÔes e exclusĂ”es de contĂȘineres.
Dica profissional: Use nosso Gerador de Comandos Docker para criar rapidamente comandos Docker complexos sem memorizar todas as flags e opçÔes.
Comandos Essenciais do Docker
Vamos percorrer os comandos Docker que vocĂȘ usarĂĄ diariamente. Eles cobrem todo o ciclo de vida do contĂȘiner, desde baixar imagens atĂ© limpar recursos.
Trabalhando com Imagens
# Baixar uma imagem do Docker Hub
docker pull ubuntu:22.04
# Listar todas as imagens locais
docker images
# Remover uma imagem
docker rmi ubuntu:22.04
# Construir uma imagem a partir de um Dockerfile
docker build -t myapp:1.0 .
# Marcar uma imagem para enviar a um registro
docker tag myapp:1.0 username/myapp:1.0
# Enviar uma imagem para um registro
docker push username/myapp:1.0
Executando ContĂȘineres
# Executar um contĂȘiner em primeiro plano
docker run ubuntu:22.04 echo "Hello Docker"
# Executar um contĂȘiner em modo desanexado (background)
docker run -d nginx
# Executar com um nome personalizado
docker run -d --name my-nginx nginx
# Executar com mapeamento de porta (host:contĂȘiner)
docker run -d -p 8080:80 nginx
# Executar com variĂĄveis de ambiente
docker run -d -e POSTGRES_PASSWORD=secret postgres
# Executar com montagem de volume
docker run -d -v /host/path:/container/path nginx
# Executar interativamente com um shell
docker run -it ubuntu:22.04 /bin/bash
Gerenciando ContĂȘineres
# Listar contĂȘineres em execução
docker ps
# Listar todos os contĂȘineres (incluindo parados)
docker ps -a
# Parar um contĂȘiner
docker stop my-nginx
# Iniciar um contĂȘiner parado
docker start my-nginx
# Reiniciar um contĂȘiner
docker restart my-nginx
# Remover um contĂȘiner
docker rm my-nginx
# Remover um contĂȘiner em execução (forçar)
docker rm -f my-nginx
# Ver logs do contĂȘiner
docker logs my-nginx
# Seguir logs em tempo real
docker logs -f my-nginx
# Executar um comando em um contĂȘiner em execução
docker exec my-nginx ls /usr/share/nginx/html
# Abrir um shell em um contĂȘiner em execução
docker exec -it my-nginx /bin/bash
# Ver uso de recursos do contĂȘiner
docker stats
# Inspecionar detalhes do contĂȘiner
docker inspect my-nginx
Comandos de Limpeza
# Remover todos os contĂȘineres parados
docker container prune
# Remover imagens nĂŁo utilizadas
docker image prune
# Remover volumes nĂŁo utilizados
docker volume prune
# Remover tudo nĂŁo utilizado (contĂȘineres, imagens, redes, volumes)
docker system prune -a
As flags -it merecem menção especial. -i mantĂ©m o STDIN aberto (interativo), e -t aloca um pseudo-TTY (terminal). Juntas, elas permitem interagir com o contĂȘiner como uma sessĂŁo de shell normal.
Dica rĂĄpida: Use docker ps -q para obter apenas IDs de contĂȘineres, o que Ă© Ăștil para scripts. Por exemplo, docker stop $(docker ps -q) para todos os contĂȘineres em execução.
Escrevendo Dockerfiles
Um Dockerfile Ă© onde a mĂĄgica acontece. Ă uma receita para construir sua imagem Docker, especificando exatamente o que vai no seu contĂȘiner. Vamos detalhar as instruçÔes mais importantes e melhores prĂĄticas.
Estrutura BĂĄsica do Dockerfile
# Começar de uma imagem base
FROM node:18-alpine
# Definir o diretĂłrio de trabalho
WORKDIR /app
# Copiar arquivos de pacote
COPY package*.json ./
# Instalar dependĂȘncias
RUN npm install
# Copiar código da aplicação
COPY . .
# Expor a porta em que sua aplicação executa
EXPOSE 3000
# Definir o comando para executar sua aplicação
CMD ["node", "server.js"]
InstruçÔes Principais do Dockerfile
FROM especifica a imagem base. Sempre use tags de versĂŁo especĂficas (como node:18-alpine) em vez de latest para garantir construçÔes reproduzĂveis. Variantes Alpine sĂŁo menores e mais seguras.
WORKDIR define o diretório de trabalho para instruçÔes subsequentes. Ele cria o diretório se não existir. Isso é mais limpo do que usar RUN cd /app.
COPY copia arquivos da sua mĂĄquina host para a imagem. A sintaxe Ă© COPY origem destino. Use COPY . . para copiar tudo, mas tenha cuidado com o que vocĂȘ inclui (use .dockerignore).
RUN executa comandos durante o processo de construção. Cada instrução RUN cria uma nova camada. Encadeie comandos com && para reduzir camadas:
# Ruim: Cria 3 camadas
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean
# Bom: Cria 1 camada
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
EXPOSE documenta em qual porta sua aplicação escuta. Ele nĂŁo publica a porta de fato â isso acontece com docker run -p.
CMD especifica o comando padrĂŁo a ser executado quando o contĂȘiner inicia. Use o formato de array JSON (["executĂĄvel", "param1"]) para evitar problemas de processamento de shell.
ENTRYPOINT Ă© similar ao CMD, mas mais difĂcil de sobrescrever. Use-o quando quiser que seu contĂȘiner se comporte como um executĂĄvel. VocĂȘ pode combinar ENTRYPOINT e CMD para padrĂ”es flexĂveis.
ConstruçÔes Multi-Estågio
ConstruçÔes multi-estĂĄgio permitem usar mĂșltiplas instruçÔes FROM em um Dockerfile. Isso Ă© incrivelmente poderoso para criar imagens de produção pequenas enquanto mantĂ©m as ferramentas de construção separadas.
# Estågio de construção
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Estågio de produção
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/server.js"]
A imagem de produção contĂ©m apenas o cĂłdigo compilado e dependĂȘncias de runtime, nĂŁo as ferramentas de construção. Isso pode reduzir o tamanho da imagem em 70% ou mais.
Arquivo .dockerignore
Crie um arquivo .dockerignore para excluir arquivos do contexto de construção. Isso acelera as construçÔes e reduz o tamanho da imagem.
node_modules
npm-debug.log
.git
.env
*.md
.DS_Store
coverage
.vscode