Aprenda / Infraestrutura — Docker

IntermediárioAula 9 de 1616 min0% da trilha

Redes Docker de verdade: bridge, host e networks customizadas

A rede automática do compose resolve o caso comum — mas isolar ambientes ou conectar projetos diferentes exige entender o que tem por trás.

Na trilha de fundamentos, subir um docker-compose.yml "simplesmente funciona": os serviços se enxergam pelo nome, sem configurar IP nenhum. Isso não é mágica do Docker em geral — é um comportamento específico da rede que o Compose cria pra você. Fora do Compose, ou quando você precisa de mais controle, existe uma camada inteira aqui que vale entender.

Os drivers de rede: bridge, host e none

Toda rede Docker usa um driver, que define como o tráfego se comporta. Os três mais comuns:

drivers de rede
bridge (customizada)   Rede isolada, virtual. Containers na mesma rede bridge customizada se
                        enxergam por NOME (DNS interno). É o que o Compose cria automaticamente.
bridge (padrão)         A rede "docker0" que existe sozinha em toda instalação do Docker. Containers
                        soltos com "docker run" sem --network caem aqui — e essa rede NÃO resolve nome
                        de container por DNS, só por IP.
host                    O container usa a rede do host diretamente, sem isolamento nem NAT. Não precisa
                        de "-p" pra publicar porta — o container já escuta direto na porta do host.
none                    Sem rede nenhuma. O container não tem nem interface de loopback além da própria.

O detalhe que costuma confundir: existe uma rede chamada "bridge" que já vem pronta com o Docker (a rede padrão), e existe o driver "bridge", que você usa pra criar outras redes, customizadas, com nome próprio. São coisas diferentes com o mesmo nome. A rede bridge padrão não faz DNS por nome de container — é por isso que, historicamente, quem usava só docker run precisava descobrir o IP do outro container na mão. Uma rede bridge customizada (criada com docker network create, ou automaticamente pelo Compose) já resolve isso.

Criando e conectando uma rede na mão

terminal
docker network create minha-rede
docker network ls

Com a rede criada, qualquer container iniciado com --network minha-rede entra nela e passa a resolver os outros containers da mesma rede pelo nome (ou pelo --name que você deu a eles).

terminal
docker run -d --name api --network minha-rede minha-api:latest
docker run -d --name worker --network minha-rede minha-api:latest node worker.js

Dentro do container worker, ping api resolve — os dois estão na mesma rede customizada, exatamente como acontece entre serviços de um mesmo docker-compose.yml.

Conectando containers de composes (ou projetos) diferentes

Por padrão, cada docker-compose.yml cria a própria rede isolada — mesmo que dois projetos estejam rodando na mesma VPS, os containers de um não enxergam os do outro. Isso é bom (isolamento), mas às vezes você precisa que dois projetos separados se falem — por exemplo, uma API que fica num repositório e um serviço de monitoramento que fica em outro. A solução é declarar uma rede externa, criada fora de qualquer compose específico, e referenciá-la nos dois arquivos.

terminal — criando a rede compartilhada uma vez
docker network create rede-compartilhada
projeto-api/docker-compose.yml
services:
  api:
    build: .
    networks:
      - default
      - rede-compartilhada

networks:
  rede-compartilhada:
    external: true
projeto-monitoramento/docker-compose.yml
services:
  monitor:
    image: monitor:latest
    networks:
      - rede-compartilhada

networks:
  rede-compartilhada:
    external: true

Com isso, monitor consegue chamar http://api:3000 mesmo os dois serviços vindo de arquivos de compose (e possivelmente pastas/repositórios) completamente diferentes — o que importa é os dois estarem conectados à mesma rede rede-compartilhada, marcada como external porque ela não foi criada por nenhum dos dois composes, já existia antes.

Inspecionando uma rede

terminal
docker network inspect rede-compartilhada

docker network inspect mostra exatamente quem está conectado, com qual IP — o primeiro lugar pra olhar quando um container "deveria" enxergar outro e não enxerga.

Por que isolar rede por ambiente importa

Se staging e produção rodam na mesma VPS sem redes separadas, um container de staging comprometido (ou só mal configurado) pode alcançar o banco de produção diretamente, sem passar por autenticação nenhuma de borda — a rede interna do Docker não sabe distinguir "ambiente de teste" de "ambiente real", só distingue quem está conectado em qual rede. Dar uma rede própria pra cada ambiente (ou pra cada projeto) faz esse isolamento existir de verdade, não só na cabeça de quem escreveu o compose.

Exercício

Dois composes na mesma VPS: loja/docker-compose.yml (serviços loja-api e loja-db) e blog/docker-compose.yml (serviços blog-api e blog-db). Eles não deveriam se enxergar. O time reclama que, ao rodar docker compose up nos dois ao mesmo tempo, nada quebrou — mas querem confirmar que estão isolados de verdade. Que comando confirma isso, e o que esperar ver?

Quiz rápido

Qual a diferença entre a rede bridge padrão do Docker e uma rede bridge customizada?
Como fazer dois containers de docker-compose.yml diferentes (projetos separados) se enxergarem pelo nome?