Qual é a diferença entre portas docker-compose e expose

461

Qual é a diferença entre portsand exposeoptions indocker-compose.yml

bibstha
fonte

Respostas:

527

De acordo com a referência docker-compor ,

Portas é definido como:

Expor portas . Especifique as duas portas (HOST: CONTAINER) ou apenas a porta do contêiner (uma porta de host aleatória será escolhida).

  • As portas mencionadas no docker-compose.yml serão compartilhadas entre os diferentes serviços iniciados pelo docker-compose.
  • As portas serão expostas à máquina host a uma porta aleatória ou uma determinada porta.

Minha docker-compose.ymlaparência é:

mysql:
  image: mysql:5.7
  ports:
    - "3306"

Se o fizer docker-compose ps, será semelhante a:

  Name                     Command               State            Ports
-------------------------------------------------------------------------------------
  mysql_1       docker-entrypoint.sh mysqld      Up      0.0.0.0:32769->3306/tcp

Expose é definido como:

Exponha portas sem publicá-las na máquina host - elas estarão acessíveis apenas aos serviços vinculados. Somente a porta interna pode ser especificada.

As portas não são expostas a máquinas host, apenas expostas a outros serviços.

mysql:
  image: mysql:5.7
  expose:
    - "3306"

Se o fizer docker-compose ps, será semelhante a:

  Name                  Command             State    Ports
---------------------------------------------------------------
 mysql_1      docker-entrypoint.sh mysqld   Up      3306/tcp
bibstha
fonte
24
seria possível explicar quais são as vantagens de especificar exposeem a docker-compose? Pelo que sei, você não precisa especificar expor para tornar as portas acessíveis aos serviços vinculados.
Juicy Juicy
3
Não deveria dizer que as portas expostas estarão disponíveis apenas para serviços na mesma rede docker (a ligação está sendo substituída na maioria das partes) ?.
meow
8
@ Juicy Eu acho que é semelhante exposeno Dockerfiles: "A instrução EXPOSE na verdade não publica a porta. Ela funciona como um tipo de documentação ..." docs.docker.com/engine/reference/builder/#expose
06 de
1
As portas substituem as configurações no nível do firewall? Acabei de notar que não abri portas para o mysql no firewall, mas elas estavam acessíveis remotamente. Eu tinha portas definidas como "3306: 3306" em vez de expor.
TekiusFanatikus
3
E lembre-se, se você usar docker-compose run, a definição de porta docker-compose.ymlé ignorada por padrão. De qualquer uso docker-compose upou fornecer o parâmetro--service-ports
Juha Untinen
177

portas :

  1. Ativa o contêiner para escutar as portas especificadas do mundo fora da janela de encaixe (pode ser a mesma máquina host ou uma máquina diferente) E também o mundo acessível dentro da janela de encaixe.
  2. Mais de uma porta pode ser especificada (é por isso que as portas não são portas)

insira a descrição da imagem aqui

expor :

  1. Ativa o contêiner para escutar uma porta específica apenas do mundo dentro da janela de encaixe E do mundo não acessível fora da janela de encaixe.
  2. Mais de uma porta pode ser especificada

insira a descrição da imagem aqui

Mehraj Malik
fonte
3
Note-se que expor permite várias portas - docs.docker.com/compose/compose-file/#expose - no entanto você só fornecer a porta interna, em vez de interno + externo
Stuart Moore
Mas o que fazer se eu quiser acessar o mundo exterior do meu contêiner? stackoverflow.com/questions/61322256/…
gstackoverflow
26

Portas Esta seção é usada para definir o mapeamento entre o servidor host e o contêiner do Docker.

ports:
   - 10005:80

Isso significa que o aplicativo em execução no contêiner é exposto na porta 80. Mas o sistema / entidade externo não pode acessá-lo, portanto, ele precisa ser mapeado para a porta do servidor host.

Nota: você precisa abrir a porta do host 10005 e modificar as regras de firewall para permitir que entidades externas acessem o aplicativo.

Eles podem usar

http: // {IP do host}: 10005

algo assim

EXPOSE Isso é usado exclusivamente para definir a porta na qual o aplicativo está sendo executado dentro do contêiner do docker.

Você também pode defini-lo no dockerfile. Geralmente, é uma prática boa e amplamente utilizada definir o EXPOSE dentro do dockerfile porque muito raramente alguém os executa em outra porta que não a porta 80 padrão

sorabzone
fonte
19

Portas

A portsseção publicará portas no host. O Docker configurará um encaminhamento para uma porta específica da rede host para o contêiner. Por padrão, isso é implementado com um processo de proxy do espaço do usuário ( docker-proxy) que escuta na primeira porta e encaminha para o contêiner, que precisa escutar no segundo ponto. Se o contêiner não estiver escutando na porta de destino, você ainda verá algo escutando no host, mas a conexão será recusada se você tentar se conectar a essa porta, a partir da falha no encaminhamento para o contêiner.

Observe que o contêiner deve estar atendendo a todas as interfaces de rede, pois esse proxy não está sendo executado no espaço de nomes de rede do contêiner e não pode alcançar 127.0.0.1 dentro do contêiner. O método IPv4 para isso é configurar seu aplicativo para escutar 0.0.0.0.

Observe também que as portas publicadas não funcionam na direção oposta. Você não pode se conectar a um serviço no host a partir do contêiner publicando uma porta. Em vez disso, você encontrará erros do docker tentando ouvir a porta do host já em uso.

Expor

Expor é documentação. Ele define metadados na imagem e, quando em execução, também no contêiner. Normalmente, você configura isso no Dockerfile com a EXPOSEinstrução e serve como documentação para os usuários que executam sua imagem, para que eles saibam em quais portas, por padrão, seu aplicativo estará ouvindo. Quando configurados com um arquivo de composição, esses metadados são definidos apenas no contêiner. Você pode ver as portas expostas ao executar um docker inspectna imagem ou contêiner.

Existem algumas ferramentas que dependem de portas expostas. Na janela de encaixe, o -Psinalizador publicará todas as portas expostas nas portas efêmeras do host. Também existem vários proxies reversos que usarão uma porta exposta ao enviar tráfego para o aplicativo, se você não definir explicitamente a porta do contêiner.

Além dessas ferramentas externas, a exposição não tem impacto algum na rede entre contêineres. Você só precisa de uma rede docker comum e de conectar-se à porta do contêiner para acessar um contêiner de outro. Se essa rede for criada pelo usuário (por exemplo, não a rede de ponte padrão denominada bridge), você poderá usar o DNS para conectar-se aos outros contêineres.

BMitch
fonte
3

Eu concordo totalmente com as respostas antes. Gostaria apenas de mencionar que a diferença entre exposição e portas faz parte do conceito de segurança no docker. Ele anda de mãos dadas com a rede do docker. Por exemplo:

Imagine um aplicativo com front-end da web e back-end de banco de dados. O mundo externo precisa acessar o front-end da web (talvez na porta 80), mas apenas o back-end em si precisa de acesso ao host e à porta do banco de dados. Usando uma ponte definida pelo usuário, apenas a porta da web precisa ser aberta e o aplicativo de banco de dados não precisa de nenhuma porta aberta, pois o front-end da web pode alcançá-lo através da ponte definida pelo usuário.

Este é um caso de uso comum ao configurar uma arquitetura de rede na janela de encaixe. Por exemplo, em uma rede de pontes padrão, não há portas acessíveis no mundo externo. Portanto, você pode abrir um ponto de entrada com "portas". Com o uso de "expor", você define a comunicação na rede. Se você deseja expor as portas padrão, não precisa definir "expor" no seu arquivo docker-compose.

medTech
fonte