Docker para iniciantes: entenda e use contêineres

1. O que é Docker e por que usar contêineres?

Docker é uma plataforma de código aberto que automatiza a implantação de aplicações dentro de contêineres — ambientes leves e isolados que empacotam o software com todas as suas dependências. Diferente das máquinas virtuais (VMs), que virtualizam o hardware e exigem um sistema operacional completo para cada instância, os contêineres compartilham o kernel do host e rodam como processos isolados no sistema.

As principais vantagens incluem:
- Portabilidade: um contêiner roda igual em qualquer ambiente que tenha Docker (desenvolvimento, teste, produção).
- Isolamento leve: cada contêiner tem seu próprio sistema de arquivos, rede e processos, sem o overhead de uma VM.
- Consistência: elimina o clássico "funciona na minha máquina" ao garantir que o ambiente de execução seja idêntico em todos os estágios.

Casos de uso comuns: desenvolvimento local padronizado, testes automatizados, deploy contínuo (CI/CD) e microsserviços.

2. Instalação e primeiros passos

Para começar, instale o Docker Desktop no site oficial (docker.com/products/docker-desktop). Após a instalação, verifique a versão:

docker --version

Execute seu primeiro contêiner:

docker run hello-world

Esse comando baixa automaticamente a imagem hello-world do Docker Hub e executa um contêiner que exibe uma mensagem de confirmação.

O ecossistema Docker é composto por:
- Imagens: templates read-only com instruções para criar contêineres.
- Contêineres: instâncias executáveis de imagens.
- Docker Hub: repositório público onde milhares de imagens estão disponíveis.

3. Trabalhando com imagens

Uma imagem Docker é um pacote leve e executável que contém tudo necessário para rodar o software: código, runtime, bibliotecas e configurações.

Baixe uma imagem do Ubuntu:

docker pull ubuntu:22.04

Liste as imagens baixadas:

docker images

Remova uma imagem não utilizada:

docker rmi ubuntu:22.04

Para criar sua própria imagem, escreva um arquivo Dockerfile:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]

Construa a imagem:

docker build -t minha-app .

4. Gerenciando contêineres

Execute um contêiner interativo com o Ubuntu:

docker run -it ubuntu:22.04 bash

Para rodar em segundo plano com um nome personalizado:

docker run -d --name meu-servidor nginx:alpine

Liste contêineres em execução:

docker ps

Liste todos os contêineres (incluindo parados):

docker ps -a

Pare e inicie um contêiner:

docker stop meu-servidor
docker start meu-servidor

Remova um contêiner parado:

docker rm meu-servidor

Visualize os logs:

docker logs meu-servidor

5. Mapeamento de portas e volumes

Para expor a porta 80 do contêiner na porta 8080 do host:

docker run -d -p 8080:80 --name web nginx:alpine

Acesse http://localhost:8080 no navegador.

Para persistir dados além do ciclo de vida do contêiner, use volumes:

docker volume create meu-volume
docker run -d -v meu-volume:/usr/share/nginx/html --name web-persistente nginx:alpine

Exemplo prático: crie um arquivo HTML local e monte-o no contêiner:

echo "<h1>Olá Docker</h1>" > index.html
docker run -d -p 8080:80 -v $(pwd)/index.html:/usr/share/nginx/html/index.html nginx:alpine

6. Redes e comunicação entre contêineres

O Docker oferece três tipos principais de rede:
- bridge (padrão): contêineres se comunicam entre si em uma rede isolada.
- host: contêiner usa a rede do host diretamente.
- none: sem rede.

Crie uma rede personalizada:

docker network create minha-rede

Execute dois contêineres conectados à mesma rede:

docker run -d --name db --network minha-rede -e MYSQL_ROOT_PASSWORD=123 mysql:8
docker run -d --name app --network minha-rede -p 3000:3000 minha-app

O contêiner app pode acessar o banco usando o nome db como hostname.

7. Docker Compose para múltiplos contêineres

Docker Compose permite definir e executar aplicações multi-contêiner com um único arquivo YAML.

Crie docker-compose.yml:

version: '3.8'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./site:/usr/share/nginx/html
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
    volumes:
      - db-data:/var/lib/mysql
  cache:
    image: redis:alpine

volumes:
  db-data:

Suba todos os serviços:

docker-compose up -d

Pare e remova tudo:

docker-compose down

8. Boas práticas e próximos passos

  • Otimize Dockerfiles: minimize o número de camadas combinando comandos RUN, use imagens base pequenas (Alpine) e adicione um .dockerignore para excluir arquivos desnecessários.
  • Limpeza regular: use docker system prune -a para remover imagens, contêineres e volumes não utilizados.
  • Segurança: evite rodar como root, use usuários não privilegiados no Dockerfile e mantenha imagens atualizadas.

Para se aprofundar, explore a documentação oficial, cursos na Udemy/Docker Mastery, e comunidades como o Docker Community Slack e o fórum do Stack Overflow.

Referências