This content originally appeared on DEV Community and was authored by Igor Oliveira
Há um tempo eu venho tentando contruir um SaaS como forma de praticar meus estudos. Durante várias ideias e tentativas, eu me deparei com um problema relacionado ao docker: por algum motivo, o Docker Desktop não queria funcionar com Windows.
O que foi estranho e pareceu ser um problema simples de resolver, acabou se tornando uma dor de cabeça tremenda e me levou a buscar novas alternativas. O uso do WSL2 se mostrou como caminho, não só para resolver um problema, mas como um tópico de estudo para além da programação.
O WSL2 não é uma simples compatibilidade de comandos UNIX dentro do Windows. Ele roda um kernel Linux completo em uma máquina virtual leve baseada em Hyper-V. Quando o Docker Desktop é configurado para usar o WSL2 como backend, todos os containers são criados dentro desse kernel Linux, e não diretamente no Windows.
A comunicação entre o Windows e o ambiente Linux do WSL2 é feita via uma interface virtual criada pelo Windows: vEthernet (WSL). Ela é, na verdade, um Switch Virtual criado automaticamente pela plataforma de virtualização do Windows (chamada Virtual Machine Platform, um componente do Hyper-V) quando o WSL2 é iniciado pela primeira vez. Essa interface atua como única ponte de rede entre dois ambientes isolados:
- O sistema operacional Windows (Host).
- O kernel Linux/VM do WSL2 (Guest).
O principal mecanismo que ela gerencia é o NAT (Network Address Translation). O Linux (WSL2 VM) recebe um IP privado (por exemplo, 172.27.x.x ou 192.168.x.x) que muda a cada reinicialização do Windows. Esse IP funciona como Gateway Padrão e Servidor DNS dentro do ambiente Linux, permitindo que o tráfego de saída seja traduzido para a rede do host. No lado do Windows, a interface vEthernet (WSL) recebe o primeiro endereço desse bloco privado (por exemplo, 172.27.x.1) e atua como o roteador/NAT responsável por gerenciar todo o tráfego entre o Windows e a VM Linux.
Teoricamente, o Docker Desktop deveria configurar o proxy automático de portas por meio da interface vEthernet (WSL), permitindo que minha aplicação no Windows acessasse o container através do endereço localhost:1433. No entanto, como optei por rodar o Docker Engine nativo diretamente na minha distribuição WSL2, eu não contava com o serviço de encaminhamento automático de portas que o Docker Desktop injeta no host Windows.
Assim, minha aplicação .NET, executando no Windows, tentava se conectar a localhost:1433. Como não havia o serviço de port forwarding do Docker Desktop, o Windows não sabia que o tráfego dessa porta deveria ser redirecionado para o endereço IP dinâmico da VM WSL2 (geralmente algo como 172.x.x.x). Por isso, a conexão falhava.
Uma alternativa para contornar esse problema foi criar uma rede personalizada no Docker e expor a porta do container do SQL Server para o host Windows. Essa configuração permitiu que o tráfego de localhost:1433 fosse corretamente roteado até o container, mesmo sem o proxy de portas do Docker Desktop.
O primeiro passo foi criar uma rede bridge isolada com suporte a DNS interno:
docker network create mynetwork
Essa rede cria uma bridge virtual (por exemplo, br-2c7e9a5d7b45) com uma sub-rede dedicada (172.18.0.0/16) e um gateway interno (172.18.0.1).
Containers conectados a ela podem se comunicar diretamente por nome, sem precisar de IP fixo.
Em seguida, subi o container do SQL Server conectado a essa rede e expus a porta 1433:
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=YourStrong!Passw0rd" \
--name sqlserver \
--network mynetwork \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2022-latest
O parâmetro -p 1433:1433 faz o mapeamento de porta entre o host (Windows) e o container, permitindo que a aplicação fora do WSL2 acesse o serviço pelo localhost:1433.
O --network mynetwork garante que, se eu decidir rodar outros containers (por exemplo, uma API .NET) dentro do WSL2, eles poderão se conectar via DNS interno — usando apenas sqlserver como host.
Para confirmar a conectividade, testei o acesso diretamente do Windows:
Test-NetConnection localhost -Port 1433
E também validei de dentro da aplicação .NET, configurando a connection string da seguinte forma:
"Server=localhost,1433;Database=MyAppDb;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;"
Após isso, a aplicação passou a se conectar normalmente ao SQL Server rodando dentro do container, mesmo com o Docker Engine isolado dentro da VM WSL2.
Mas, por que essa solução funciona?
Ao expor a porta (-p 1433:1433), o Docker criou uma regra de DNAT (Destination NAT) na tabela iptables do Linux interno do WSL2. Essa regra instrui o kernel a redirecionar todo o tráfego recebido na porta 1433 do host (interface eth0) para o IP interno do container SQL Server.
Quando o Windows acessa localhost:1433, o pacote é enviado à interface vEthernet (WSL) → traduzido pelo NAT → entregue à bridge br-xxxxx → e finalmente roteado ao container. Com isso, o comportamento esperado do Docker Desktop foi restaurado manualmente, mas de forma controlada e previsível.
This content originally appeared on DEV Community and was authored by Igor Oliveira
Igor Oliveira | Sciencx (2025-11-05T01:16:32+00:00) WSL2 e Docker sem Docker Desktop: configurando NAT e acesso localhost manualmente. Retrieved from https://www.scien.cx/2025/11/05/wsl2-e-docker-sem-docker-desktop-configurando-nat-e-acesso-localhost-manualmente/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.