O que é Docker e por que os desenvolvedores devem aprender?
Uma análise prática de Docker para desenvolvedores: containers vs VMs, comandos essenciais, Dockerfiles e como começar a usar em projetos reais.
Docker aparece constantemente em anúncios de emprego e guias de configuração, e se você nunca trabalhou com containers pode parecer uma barreira que precisa ultrapassar antes de escrever código de verdade. Não é tão complicado depois que você passa pelo vocabulário.
O que um container realmente é
Um container empacota sua aplicação com tudo que ela precisa para rodar: o código, runtime, bibliotecas do sistema e arquivos de configuração. Não é uma máquina virtual. Uma VM virtualiza um sistema operacional inteiro, kernel incluído, o que significa que iniciar uma pode levar um minuto e consumir alguns gigabytes de RAM. Um container compartilha o kernel da máquina host e apenas isola o processo, então inicia em menos de um segundo e normalmente usa dezenas de megabytes em vez de gigabytes.
Essa diferença é por que Docker conquistou o desenvolvimento local e os pipelines de CI tão rapidamente. Você pode iniciar um banco de dados Postgres, um cache Redis e seu servidor de app em um único laptop sem instalar nenhum deles diretamente no seu OS.
Os componentes principais que você precisa conhecer
Existem quatro termos que cobrem a maioria do que você vai lidar dia a dia:
- Image: um template somente leitura construído a partir de um Dockerfile. Pense nela como um snapshot de um filesystem mais metadados sobre como executá-la.
- Container: uma instância em execução de uma image. Você pode iniciar, parar e deletar containers sem tocar na image de origem.
- Dockerfile: um arquivo de texto com instruções para construir uma image, linha por linha.
- Registry: onde as images são armazenadas e baixadas, mais comumente Docker Hub.
Um Dockerfile mínimo para uma app Node.js se parece com isto:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Construa com docker build -t my-app . e execute com docker run -p 3000:3000 my-app. A flag -p mapeia uma porta na sua máquina para uma porta dentro do container, é assim que você realmente alcança a app pelo navegador.
Comandos que você vai usar constantemente
Um punhado de comandos cobre a maioria do trabalho diário:
docker ps— listar containers em execuçãodocker ps -a— listar todos os containers, incluindo os paradosdocker images— listar images na sua máquinadocker logs <container>— verificar output de um container em execução ou travadodocker exec -it <container> sh— abrir um shell dentro de um container em execuçãodocker rm/docker rmi— limpar containers e images que você não precisa mais
Esse último par importa mais do que as pessoas esperam. Docker deixará o espaço em disco desaparecer em images antigas e containers parados sem problemas. Executar docker system prune ocasionalmente recupera uma quantidade surpreendente de espaço.
Por que docker-compose muda o fluxo de trabalho
A maioria dos projetos reais precisa de mais de um container: um servidor de app, um banco de dados, talvez um cache. Escrever comandos docker run para cada um fica entediante rápido. docker-compose.yml deixa você definir todo o stack em um arquivo:
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpassword
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Execute docker compose up e ambos os serviços iniciam juntos, conectados em rede para que web possa alcançar db pelo nome do serviço. Essa é a configuração que você vai ver no README de quase todo repo open-source, e entender isto significa que você pode clonar um projeto e tê-lo rodando em minutos em vez de instalar manualmente Postgres, Redis e tudo mais que a app precisa.
Onde as pessoas tropeçam no começo
Volumes confundem quase todo mundo no início. Sem um volume, qualquer coisa escrita dentro de um container desaparece quando o container é removido, o que é um problema para bancos de dados. A seção volumes no arquivo compose acima mapeia um volume nomeado para um caminho dentro do container para que dados sobrevivam a reinicializações.
Outro erro comum é copiar node_modules ou .git na image porque não há arquivo .dockerignore. Adicione um assim como um .gitignore:
node_modules
.git
.env
Isso mantém os builds mais rápidos e as images menores, o que importa uma vez que você está enviando images para um registry ou fazendo deploy para Kubernetes.
Onde ir depois do básico
Uma vez que construir e executar containers se sinta normal, as próximas habilidades úteis são multi-stage builds para images de produção menores, entender modos de networking do Docker e ler uma saída de docker inspect quando algo não está se conectando certo. Nada é difícil, é só desconhecido na primeira vez.
Para mais sobre containerizar aplicações reais e conectá-las a pipelines de deploy em nuvem, confira os segmentos DevOps e Cloud na Korra Studio.
Escrito com assistência de IA, revisado e publicado por Michal Pilch (CISSP), Korra Studio.
Esta é uma anotação da base de conhecimento da Korra Studio — a plataforma associa cada tema com mentoria 1-para-1.
Começar gratuitamentearrow_forward