Como se conectar a um contêiner docker de fora do host (mesma rede)

Eu criei meu primeiro contêiner docker, ele está executando um servidor usando o Go, mas não consigo acessá-lo de fora do computador host. Eu comecei com o docker, então estou um pouco perdido aqui.

Então eu tenho um Go code muito simples que inicia um servidor, eu construí a imagem do docker que instala o Go e constrói o código em uma imagem base do Linux. Estou executando o servidor na porta 8080, portanto, exponho essa porta ao host que está executando o contêiner da seguinte forma:

docker run -p 8080:8080 dockertest 

Isso funciona e eu consigo acessar o servidor através do IP da máquina do docker (aquele que aparece no Docker Quickstart Terminal quando iniciado), o problema é que não consigo acessar o site que estou hospedando fora do host, então se eu tentar para abrir o mesmo endereço IP no meu telefone, isso só me dá um erro: Esta página da Web não está disponível (ERR_CONNECTION_TIMED_OUT).

Eu também tentei especificar o IP assim:

 docker run -p 192.168.0.157:8080:8080 dockertest 

Mas quando faço isso, posso acessar o site por meio do IP da estação de encaixe nem do IP especificado na linha de comando acima. Eu também não tenho certeza qual IP eu devo escrever nesse comando Eu usei o IP do meu computador, eu também tentei 127.0.0.1 (localhost) mas isso me deu o mesmo resultado: não podia acessar o site através de qualquer IP qualquer.

Eu pesquisei no Google esse problema e encontrei muitas perguntas sobre o StackOverflow, mas elas não me ajudaram a resolver meu problema, a maioria delas era orientada para Linux ou Mac, então a solução não se aplicava à minha situação.

Além disso, posso executar o código Go no meu computador e acessar o site a partir de outro dispositivo na mesma rede através do IP do meu computador. Eu não entendo porque eu não posso acessá-lo quando eu estou rodando ele na máquina docker, ocorreu-me que pode ter algo a ver com o encaminhamento de IP ou algo assim, mas eu sou um noob completo em rede, eu Sou principalmente um desenvolvedor web e quase não tenho experiência em nativo.

TL; DR Verifique o modo de rede do seu host VirtualBox – ele deve ser bridged se você quiser que a máquina virtual (e o contêiner Docker que ele hospeda) esteja acessível em sua rede local.


Parece que a sua confusão está em qual host se conectar para acessar seu aplicativo via HTTP. Você não especificou realmente qual é a sua configuração – eu vou fazer algumas suposições, com base no fato de que você tem “Windows” e “VirtualBox” em suas tags.

Eu estou supondo que você tem Docker rodando em algum sabor de Linux em execução no VirtualBox em um host do Windows. Vou rotular os endereços IP da seguinte maneira:

D = o endereço IP do contêiner do Docker

L = o endereço IP do host Linux em execução no VirtualBox

W = o endereço IP do host do Windows

Quando você executa seu aplicativo Go em seu host do Windows, pode se conectar a ele com http://W:8080/ de qualquer lugar em sua rede local. Isso funciona porque o aplicativo Go liga a porta 8080 na máquina Windows e qualquer pessoa que tentar acessar a porta 8080 no endereço IP W será conectada.

E aqui é onde se torna mais complicado:

O VirtualBox, quando configura uma máquina virtual (VM), pode configurar a rede em um dos vários modos diferentes. Não me lembro de todas as diferentes opções, mas a que você quer é bridged . Nesse modo, o VirtualBox conecta a máquina virtual à sua rede local como se fosse uma máquina independente na rede, como qualquer outra máquina conectada à sua rede. No modo em bridged , a máquina virtual aparece em sua rede como qualquer outra máquina. Outros modos configuram as coisas de maneira diferente e a máquina não ficará visível na sua rede.

Portanto, supondo que você configurou a rede corretamente para o host Linux (em bridged ), o host Linux terá um endereço IP em sua rede local (algo como 192.168.0.x) e você poderá acessar seu contêiner Docker em http://L:8080/ .

Se o host do Linux estiver configurado para algum modo diferente de bridged , você poderá acessar a partir do host do Windows, mas isso dependerá exatamente de qual modo ele está.

EDIT – com base nos comentários abaixo, parece que a situação descrita acima está correta.

Vamos voltar um pouco: aqui está como o Docker funciona no meu computador (Ubuntu Linux).

Imagine que eu executo o mesmo comando que você tem: docker run -p 8080:8080 dockertest . O que isso faz é iniciar um novo contêiner baseado na imagem da dockertest e a porta de encaminhamento (conexão) 8080 no host Linux (meu PC) para a porta 8080 no contêiner. O Docker configura sua própria rede interna (com seu próprio conjunto de endereços IP) para permitir que o daemon do Docker se comunique e permitir que os contêineres se comuniquem uns com os outros. Então, basicamente o que você está fazendo com isso -p 8080:8080 é conectar a rede interna do Docker com a rede “externa” – ou seja. o adaptador de rede do host – em uma porta específica.

Comigo até agora? OK, agora vamos dar um passo para trás e olhar para o seu sistema. Sua máquina está executando o Windows – o Docker não (atualmente) é executado no Windows, portanto, a ferramenta que você está usando configurou um host Linux em uma máquina virtual do VirtualBox. Quando você docker run a docker run em seu ambiente, ocorre exatamente a mesma coisa – a porta 8080 no host Linux está conectada à porta 8080 no contêiner. A grande diferença aqui é que o host do Windows não é o host do Linux no qual o contêiner está sendo executado. Portanto, há outra camada aqui e a comunicação dessa camada com problemas.

O que você precisa é uma das duas coisas:

  1. para conectar a porta 8080 na VM do VirtualBox à porta 8080 no host do Windows, assim como você conecta o contêiner do Docker à porta do host.

  2. para conectar a VM do VirtualBox diretamente à sua rede local com o modo de rede em bridged que descrevi acima.

Se você escolher a primeira opção, poderá acessar o contêiner em http://W:8080 onde W é o endereço IP ou o nome do host do host do Windows. Se você optar pelo segundo, será possível acessar o contêiner em http://L:8080 que L é o endereço IP ou o nome do host da VM do Linux.

Então essa é toda a explicação de alto nível – agora você precisa descobrir como alterar a configuração da VM do VirtualBox. E aqui é onde eu não posso realmente ajudar você – eu não sei qual ferramenta você está usando para fazer tudo isso em sua máquina Windows e não estou familiarizado com o uso do Docker no Windows.

Se você puder acessar a janela de configuração do VirtualBox, poderá fazer as alterações descritas abaixo. Há também um cliente de linha de comando que modificará as VMs, mas não estou familiarizado com isso.

Para o modo em bridged (e essa é a escolha mais simples), desligue sua VM, clique no botão “Configurações” na parte superior e mude o modo de rede para bridged , depois reinicie a VM e pronto. A VM deve pegar um endereço IP em sua rede local via DHCP e deve estar visível para outros computadores na rede nesse endereço IP.

  1. Abra o Oracle VM VirtualBox Manager
  2. Selecione a VM usada pelo Docker
  3. Clique em Configurações -> Rede
  4. Adaptador 1 deve (padrão?) Ser “Anexado a: NAT”
  5. Clique em Avançado -> Port Forwarding
  6. Adicionar regra: protocolo TCP, porta do host 8080, porta de convidado 8080 (deixe o IP do host e o IP convidado vazios)
  7. Guest é seu contêiner docker e o Host é sua máquina

Agora você deve poder navegar até seu contêiner via localhost: 8080 e seu-interno-ip: 8080.

Depois de tentar várias coisas, isso funcionou para mim:

  • use a sinalização –publish = 0.0.0.0: 8080: 8080 docker
  • defina o modo de rede da checkbox virtual para NAT e não use nenhum encaminhamento de porta

Com endereços diferentes de 0.0.0.0 não tive sucesso.

Descobri que, além de definir os valores da porta -p, o Docker para Windows usa o vpnkit e o tráfego de input, pois estava desativado por padrão no firewall da máquina host. Depois de ativar as regras TCP de input para o vpnkit, consegui acessar meus contêineres de outras máquinas na rede local.