Короткий ответ:
EXPOSE
это способ документирования
--publish
(или -p
) является способом отображения на хост - порт к включенному контейнерного порта
Обратите внимание, что ниже:
EXPOSE
связано с Dockerfiles
( документирование )
--publish
связано с docker run ...
( выполнение / время выполнения )
Разоблачение и публикация портов
В сети Docker есть два разных механизма, которые напрямую задействуют сетевые порты: открывающие и публикующие порты. Это относится к мостовой сети по умолчанию и пользовательским мостовым сетям.
Вы EXPOSE
открываете порты, используя ключевое слово в Dockerfile или --expose
флаг для запуска Docker . Предоставление портов - это способ документировать, какие порты используются, но на самом деле не отображает и не открывает какие-либо порты . Разоблачение портов не является обязательным.
Вы публикуете порты, используя --publish
или--publish-all
флагаdocker run
. Это сообщает Docker, какие порты открывать в сетевом интерфейсе контейнера. Когда порт публикуется, он сопоставляется с доступным портом высокого порядка (выше, чем 30000
) на хост-компьютере, если только вы не укажете порт, который будет отображаться на хост-компьютере во время выполнения. Вы не можете указать порт для сопоставления на хост-машине при создании образа (в Dockerfile), потому что нет способа гарантировать, что порт будет доступен на хост-машине, на которой вы запускаете образ .
от: Docker контейнерные сети
Обновление за октябрь 2019 года : вышеуказанный фрагмент текста больше не находится в документации, но архивная версия находится здесь: docs.docker.com/v17.09/engine/userguide/networking/#exposing-and-publishing-ports
Возможно текущая документация ниже:
Опубликованные порты
По умолчанию при создании контейнера он не публикует свои порты во внешнем мире. Чтобы сделать порт доступным для служб вне Docker или для контейнеров Docker, которые не подключены к сети контейнера, используйте флаг --publish
или -p
. Это создает правило брандмауэра, которое сопоставляет порт контейнера с портом на хосте Docker.
и можно найти здесь: docs.docker.com/config/containers/container-networking/#published-ports
Также,
ПОДВЕРГАТЬ
... EXPOSE
Инструкция фактически не публикует порт . Он функционирует как тип документации между человеком, который создает образ, и человеком, который запускает контейнер, о том, какие порты предназначены для публикации.
от: ссылка на Dockerfile
Доступ к услуге, когда EXPOSE
/ --publish
не определены:
В ответе @Golo Roden говорится, что:
«Если вы не укажете ни один из них, служба в контейнере не будет доступна нигде, кроме как внутри самого контейнера».
Возможно, именно так и было во время написания ответа, но теперь кажется, что даже если вы не используете EXPOSE
или --publish
, host
и другие containers
пользователи той же сети смогут получить доступ к службе, которую вы можете запустить внутри этого контейнера.
Как проверить это:
Я использовал следующее Dockerfile
. По сути, я начинаю с Ubuntu и устанавливаю крошечный веб-сервер:
FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd
Я build
изображение как «testexpose» и run
новый контейнер с:
docker run --rm -it testexpose bash
Внутри контейнера я запускаю несколько экземпляров mini-httpd
:
root@fb8f7dd1322d:/# mini_httpd -p 80
root@fb8f7dd1322d:/# mini_httpd -p 8080
root@fb8f7dd1322d:/# mini_httpd -p 8090
Затем я могу использовать curl
хост или другие контейнеры для загрузки домашней страницы mini-httpd
.