Я экспериментирую с Dockerfiles и думаю, что понимаю большую часть логики. Однако я не вижу разницы между «выставлением» и «публикацией» порта в этом контексте.
Все учебники, которые я видел, сначала включают EXPOSE
команду в Dockerfile:
...
EXPOSE 8080
...
Затем они создают образ из этого Dockerfile:
$ docker build -t an_image - < Dockerfile
А затем опубликуйте тот же порт, что и выше, при запуске образа:
$ docker run -d -p 8080 an_image
или опубликовать все порты, используя
$ docker run -d -P an_image
Какой смысл выставлять порт в Dockerfile, если он все равно будет опубликован? Возникает ли когда-нибудь необходимость выставлять порт, а не публиковать его позже? По сути, я хотел бы указать все порты, которые я буду использовать в Dockerfile при создании образа, а затем не беспокоиться о них снова, запустив их просто с помощью:
$ docker run -d an_image
Это возможно?
EXPOSE
и-p
а не три пули точки прецедентов. Я немного запутался там.EXPOSE
, но вы же указать-p
. Насколько я понимаю, если вы всегда используете-p
и запускаете отдельные контейнеры, тоEXPOSE
это можно пропустить, но это становится полезным / необходимым при использовании-P
или--link
. (И поскольку вы не знаете, как другие люди будут использовать ваше изображение,EXPOSE
следует указать это в любых общедоступных изображениях.)Короткий ответ:
EXPOSE
это способ документирования--publish
(или-p
) является способом отображения на хост - порт к включенному контейнерного портаОбратите внимание, что ниже:
EXPOSE
связано сDockerfiles
( документирование )--publish
связано сdocker run ...
( выполнение / время выполнения )Также,
Доступ к услуге, когда
EXPOSE
/--publish
не определены:В ответе @Golo Roden говорится, что:
Возможно, именно так и было во время написания ответа, но теперь кажется, что даже если вы не используете
EXPOSE
или--publish
,host
и другиеcontainers
пользователи той же сети смогут получить доступ к службе, которую вы можете запустить внутри этого контейнера.Как проверить это:
Я использовал следующее
Dockerfile
. По сути, я начинаю с Ubuntu и устанавливаю крошечный веб-сервер:Я
build
изображение как «testexpose» иrun
новый контейнер с:Внутри контейнера я запускаю несколько экземпляров
mini-httpd
:Затем я могу использовать
curl
хост или другие контейнеры для загрузки домашней страницыmini-httpd
.источник
172.17.0.2
) и все порты, которые я упоминаю. Если вы используете Docker для Mac / Windows, сеть отличается. Там нетdocker0
моста.См. Официальную ссылку на документацию: https://docs.docker.com/engine/reference/builder/#expose.
EXPOSE
Позволяют определить частный (контейнер) и общественных (хост) портов , чтобы выставить на изображение время сборки, когда контейнер работает , если вы запустите контейнер-P
.Публичный порт и протокол являются необязательными, если не указан общедоступный порт, на хосте docker будет выбран случайный порт, чтобы открыть указанный порт контейнера в Dockerfile.
Хорошая практика - не указывать публичный порт, поскольку он ограничивает только один контейнер на хост (второй контейнер выбрасывает порт, который уже используется).
Вы можете использовать
-p
вdocker run
контролировать то , что общественный порт открытые контейнерные порты будут соединяться.Во всяком случае, если вы не используете
EXPOSE
(с-P
включенным Docker), ни-p
один порт не будет открыт.Если вы всегда использовать
-p
на которыеdocker run
вам не нужны ,EXPOSE
но если вы используетеEXPOSE
вашуdocker run
команду может быть более простым,EXPOSE
может быть полезно , если вы не все равно , что порт будет экспонировать на хосте, или , если вы уверены , что только один контейнер будет загружен.источник
Вы открываете порты, используя ключевое слово EXPOSE в Dockerfile или флаг --expose для запуска Docker. Предоставление портов - это способ документировать, какие порты используются, но на самом деле не отображает и не открывает какие-либо порты. Разоблачение портов не является обязательным.
Источник: github commit
источник
Большинство людей используют docker compose с сетями. В документации говорится:
Это означает, что если вы используете сети для связи между контейнерами, вам не нужно беспокоиться о разоблачении портов.
источник
EXPOSE используется для сопоставления локального порта с контейнерным портом, т. Е. Если вы указываете expose в файле Docker, например
EXPOSE 8090
Что он сделает, это отобразит локальный хост-порт 8090 на контейнерный порт 8090
источник