Ответы:
Согласно справочнику docker-compose ,
Выставить порты . Либо укажите оба порта (HOST: CONTAINER), либо просто порт контейнера (будет выбран случайный порт хоста).
Моя docker-compose.yml
выглядит так:
mysql:
image: mysql:5.7
ports:
- "3306"
Если я это сделаю docker-compose ps
, это будет выглядеть так:
Name Command State Ports
-------------------------------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:32769->3306/tcp
Открывайте порты, не публикуя их на хост-машине - они будут доступны только для связанных сервисов. Можно указать только внутренний порт.
Порты не отображаются на хост-машинах, только на других сервисах.
mysql:
image: mysql:5.7
expose:
- "3306"
Если я это сделаю docker-compose ps
, это будет выглядеть так:
Name Command State Ports
---------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp
expose
Dockerfiles: «Инструкция EXPOSE фактически не публикует порт. Она работает как тип документации ...» docs.docker.com/engine/reference/builder/#expose
docker-compose run
, определение порта в docker-compose.yml
это игнорируется по умолчанию. Либо используйте, docker-compose up
либо предоставьте параметр--service-ports
порты :
выставить :
Порты Этот раздел используется для определения соответствия между хост-сервером и контейнером Docker.
ports:
- 10005:80
Это означает, что приложение, работающее внутри контейнера, открыто на порт 80. Но внешняя система или объект не могут получить к нему доступ, поэтому его необходимо сопоставить с портом хост-сервера.
Примечание. Необходимо открыть порт хоста 10005 и изменить правила брандмауэра, чтобы разрешить внешним объектам доступ к приложению.
Они могут использовать
http: // {host IP}: 10005
что-то вроде этого
EXPOSE Это используется исключительно для определения порта, на котором приложение работает внутри контейнера Docker.
Вы также можете определить это в dockerfile. Как правило, это хорошая и широко используемая практика для определения EXPOSE внутри dockerfile, потому что очень редко кто-либо запускает их на другом порту, чем порт 80 по умолчанию
В ports
разделе будут публиковаться порты на хосте. Docker настроит переадресацию для определенного порта из хост-сети в контейнер. По умолчанию это реализуется с помощью процесса прокси-сервера пользователя (docker-proxy
), который прослушивает первый порт, и пересылается в контейнер, который должен прослушивать вторую точку. Если контейнер не прослушивает порт назначения, вы все равно увидите что-то прослушивающее на хосте, но получит отказ в соединении, если вы попытаетесь подключиться к этому порту хоста из-за сбоя пересылки в ваш контейнер.
Обратите внимание, что контейнер должен прослушивать все сетевые интерфейсы, поскольку этот прокси-сервер не работает в сетевом пространстве имен контейнера и не может достичь 127.0.0.1 внутри контейнера. Метод IPv4 для этого заключается в настройке приложения для прослушивания 0.0.0.0
.
Также обратите внимание, что опубликованные порты не работают в обратном направлении. Вы не можете подключиться к службе на хосте из контейнера, опубликовав порт. Вместо этого вы обнаружите ошибки докера, пытающиеся прослушать уже используемый порт хоста.
Expose это документация. Он устанавливает метаданные на изображении, а при запуске - и на контейнере. Обычно вы конфигурируете это в Dockerfile с помощью EXPOSE
инструкции, и она служит документацией для пользователей, запускающих ваш образ, чтобы они знали, по каким портам по умолчанию будет прослушивать ваше приложение. При настройке с помощью файла компоновки эти метаданные устанавливаются только для контейнера. Вы можете увидеть открытые порты при запуске docker inspect
на образе или контейнере.
Есть несколько инструментов, которые полагаются на открытые порты. В докере -P
флаг будет публиковать все открытые порты на временных портах хоста. Существуют также различные обратные прокси, которые по умолчанию будут использовать незащищенный порт при отправке трафика в ваше приложение, если вы явно не зададите порт контейнера.
Помимо этих внешних инструментов, expose не оказывает никакого влияния на взаимодействие между контейнерами. Вам нужна только общая сеть докеров и подключение к порту контейнера, чтобы получить доступ к одному контейнеру из другого. Если эта сеть создана пользователем (например, не называется мостовой сетью по умолчанию bridge
), вы можете использовать DNS для подключения к другим контейнерам.
Я полностью согласен с ответами раньше. Я просто хотел бы отметить, что различие между expose и портами является частью концепции безопасности в Docker. Это идет рука об руку с сетью докера. Например:
Представьте себе приложение с веб-интерфейсом и базой данных. Внешний мир нуждается в доступе к веб-интерфейсу (возможно, через порт 80), но только самому серверу необходим доступ к хосту и порту базы данных. При использовании определенного пользователем моста необходимо открыть только веб-порт, а приложению базы данных не нужно открывать никаких портов, поскольку веб-интерфейс может достичь его через определенный пользователем мост.
Это частый случай использования при настройке сетевой архитектуры в Docker. Например, в мостовой сети по умолчанию недоступны порты из внешнего мира. Для этого вы можете открыть точку входа с помощью «портов». С помощью «выставить» вы определяете связь внутри сети. Если вы хотите выставить порты по умолчанию, вам не нужно определять «выставлять» в вашем файле docker-compose.
expose
вdocker-compose
? Насколько я могу судить, вам не нужно указывать expose, чтобы сделать порты доступными для связанных служб.