Quando instalamos o Docker em um Ubuntu Server 24.04, ele automaticamente cria uma infraestrutura de rede virtual que permite a comunicação entre containers e também o acesso à rede externa (internet). Neste post vamos explicar como isso funciona e mostrar esquemas visuais que ajudam a compreender a arquitetura.
1. Interfaces de Rede no Docker
No host (servidor Ubuntu), você possui uma interface física conectada à sua rede local/internet (por exemplo, enp7s0
). Essa interface é responsável por enviar e receber pacotes reais.
Quando o Docker é instalado, ele cria automaticamente uma bridge virtual chamada docker0
. Essa bridge atua como um switch virtual, permitindo que todos os containers conectados à rede padrão “bridge” consigam se comunicar entre si e com o host.
Cada container, ao ser iniciado, recebe uma interface de rede virtual chamada eth0
. Essa interface é conectada ao host por meio de um par de interfaces virtuais (veth-pair):
- Um lado fica dentro do container (
eth0
). - O outro lado aparece no host (por exemplo,
vethXYZ
) e é conectado à bridgedocker0
.
2. Esquema da Arquitetura de Rede Docker
A imagem abaixo mostra como as interfaces virtuais se conectam entre containers, a bridge docker0
e a interface de rede física do host:
veth-pairs: No host aparecem como veth1
e veth2
, conectando respectivamente ao eth0
do Backend (172.17.0.2) e ao eth0
do MongoDB (172.17.0.3), FrontEnd(172.17.0.4).
- Containers recebem IPs privados na sub-rede
172.17.0.0/16
(exemplo:172.17.0.2
,172.17.0.3, 172.17.0.4
). - docker0 funciona como o gateway dessa rede (exemplo:
172.17.0.1
). - veth-pairs conectam cada container à bridge.
3. Fluxo de Tráfego
Saída (Container → Internet)
- O pacote sai do
eth0
do container. - Passa pelo
veth-pair
até a bridgedocker0
. - É roteado/NATeado pelo host (iptables).
- Sai pela interface física (
enp7s0
) com o IP do host.
Entrada (Internet → Container)
- O pacote chega na interface física (
enp7s0
) com destino ao host. - O iptables faz o redirecionamento (port forwarding) para a
docker0
. - O pacote segue para o
veth-pair
do container correto. - Chega ao
eth0
dentro do container.
4. Benefícios do Modelo
- Isolamento: cada container tem sua própria pilha de rede.
- Flexibilidade: é possível criar redes adicionais (bridge, overlay, macvlan, etc.).
- Conectividade: containers podem se comunicar entre si e acessar serviços externos sem necessidade de configuração manual complicada.
5. Como Funciona
O que acontece quando você faz docker run -p 3000:3000 backend
é mais ou menos isso:
O container backend abre a porta 3000 interna (
172.17.0.2:3000
).O Docker cria regras no iptables do host:
Assim, quando alguém acessa
http://IP_DO_HOST:3000
, o pacote entra na interface física (eth0
), passa pelo NAT do iptables, é redirecionado para o container backend, e volta pelo mesmo caminho.
📊 Mini-diagrama extra (focado no NAT/iptables da porta 3000):
E as regras NAT/masquerade garantem que o Backend responda como se fosse o próprio host.
6. Exemplo prático
configuração considerando os requisitos:
Containers:
Backend (porta 3000)
Frontend (porta 80)
MongoDB (porta interna, sem exposição externa)
Regras:
O MongoDB deve ser acessível apenas pela rede interna Docker, não sendo exposto ao host nem ao público.
O Frontend deve estar acessível externamente via porta 80.
O Backend deve estar acessível externamente via porta 3000.
Tanto Frontend quanto Backend devem conseguir acessar o MongoDB via rede interna.
🔹 Passo 1: Criar uma rede Docker bridge personalizada
Essa rede bridge (app_net
) será usada para a comunicação interna entre os containers.
🔹 Passo 2: Subir os containers
MongoDB (somente rede interna, sem exposição externa)
Aqui não usamos
-p
, ou seja, o MongoDB não é acessível externamente, apenas pela rede internaapp_net
.
Backend (exposto na porta 3000)
O
-p 3000:3000
expõe o backend para acesso externo.
Dentro da rede interna, ele acessa o MongoDB pelo hostnamemongodb
.
Frontend (exposto na porta 80)
O
-p 80:80
expõe o frontend externamente.
Ele se comunica com o backend pelo hostname internobackend
.
🔹 Passo 3: Verificar conectividade
Ambos devem resolver os nomes automaticamente, já que estão na rede app_net
.
✅ Resumo do fluxo:
Usuário acessa
http://servidor:80
→ Frontend.Frontend se comunica com Backend pela rede interna (
http://backend:3000
).Backend acessa MongoDB internamente (
mongodb:27017
).MongoDB não é exposto ao host, garantindo segurança.
Deixe um comentário