Estou experimentando Dockerfiles e acho que entendo a maior parte da lógica. No entanto, não vejo a diferença entre "expor" e "publicar" uma porta nesse contexto.
Todos os tutoriais que vi primeiro incluem o EXPOSE
comando no Dockerfile:
...
EXPOSE 8080
...
Em seguida, eles criam uma imagem a partir deste Dockerfile:
$ docker build -t an_image - < Dockerfile
E publique a mesma porta acima ao executar a imagem:
$ docker run -d -p 8080 an_image
ou publique todas as portas usando
$ docker run -d -P an_image
Qual é o sentido de expor uma porta no Dockerfile, se ela será publicada de qualquer maneira? Seria necessário expor uma porta primeiro e não publicá-la mais tarde? Efetivamente, eu gostaria de especificar todas as portas que usarei no Dockerfile ao criar a imagem e não me incomodar com elas novamente, executando-as simplesmente com:
$ docker run -d an_image
Isso é possível?
EXPOSE
e-p
e não os três pontos de bala precedentes. Me confundiu um pouco.EXPOSE
, mas você se especificar-p
. Entendo que, se você sempre usa-p
e executa contêineres individuais, nãoEXPOSE
há problema em omitir, mas isso se torna útil / necessário ao usar-P
or--link
. (E já que você não sabe como as outras pessoas vão usar sua imagem,EXPOSE
devem ser especificadas em quaisquer imagens públicas.)Resposta curta:
EXPOSE
é uma maneira de documentar--publish
(ou-p
) é uma maneira de mapear uma porta host para uma porta de contêiner em execuçãoObserve abaixo que:
EXPOSE
está relacionado aDockerfiles
( documentação )--publish
está relacionado adocker run ...
( execução / tempo de execução )Além disso,
Acesso ao serviço quando
EXPOSE
/--publish
não está definido:Na resposta de @Golo Roden, afirma-se que:
Talvez tenha sido o caso no momento em que a resposta estava sendo escrita, mas agora parece que, mesmo se você não usar
EXPOSE
ou--publish
, ahost
outracontainers
rede da mesma rede poderá acessar um serviço que você pode iniciar dentro desse contêiner.Como testar isso:
Eu usei o seguinte
Dockerfile
. Basicamente, eu começo com o ubuntu e instalo um pequeno servidor web:Eu
build
a imagem como "testexpose" erun
um novo contêiner com:Dentro do contêiner, inicio algumas instâncias de
mini-httpd
:Sou capaz de usar a
curl
partir do host ou de outros contêineres para buscar a home page domini-httpd
.fonte
172.17.0.2
) e todas as portas que estou mencionando. Se você estiver usando o Docker para Mac / Windows, a rede será diferente. Não hádocker0
ponte.Consulte a referência da documentação oficial: https://docs.docker.com/engine/reference/builder/#expose
Isso
EXPOSE
permite que você defina portas privadas (contêiner) e públicas (host) para expor no momento da criação da imagem quando o contêiner estiver em execução, se você o executar-P
.A porta pública e o protocolo são opcionais; se nenhuma porta pública for especificada, uma porta aleatória será selecionada no host pela janela de encaixe para expor a porta do contêiner especificado no Dockerfile.
Uma boa prática é não especificar porta pública, porque limita apenas um contêiner por host (um segundo contêiner lançará uma porta já em uso).
Você pode usar
-p
emdocker run
controlar o que porto público dos portos de contentores expostos vai ser ligada.De qualquer forma, se você não usar
EXPOSE
(com o-P
docker run) nem-p
, nenhuma porta será exposta.Se você sempre usa
-p
emdocker run
você não precisaEXPOSE
, mas se você usarEXPOSE
o seudocker run
comando pode ser mais simples,EXPOSE
pode ser útil se você não se importa em qual porta será expor no host, ou se você tem certeza de apenas um contêiner será carregado.fonte
Você expõe portas usando a palavra-chave EXPOSE no Dockerfile ou o sinalizador --expose à execução do docker. Expor portas é uma maneira de documentar quais portas são usadas, mas na verdade não mapeia nem abre nenhuma porta. A exposição de portas é opcional.
Fonte: github commit
fonte
A maioria das pessoas usa o docker compor com redes. A documentação declara:
O que significa que, se você usa redes para comunicação entre contêineres, não precisa se preocupar em expor portas.
fonte
EXPOSE é usado para mapear a porta do contêiner de porta local, ou seja: se você especificar exposto no arquivo docker, como
EXPOSE 8090
O que será feito mapeará a porta 8090 do host local para a porta 8090 do contêiner
fonte