В чем разница между ports
и опциями expose
в docker-compose.yml
В чем разница между портами-док-станциями и открытием
Ответ 1
Согласно справочнику docker-compose,
Порты определяются как:
Выставить порты. Либо укажите оба порта (HOST: CONTAINER), либо просто порт контейнера (будет выбран случайный порт хоста).
- Порты, упомянутые в docker-compose.yml, будут совместно использоваться различными службами, запускаемыми docker-compose.
- Порты будут выставлены на хост-машину с произвольным портом или заданным портом.
Мой 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
Expose определяется как:
Открывайте порты, не публикуя их на хост-машине - они будут доступны только для связанных служб. Можно указать только внутренний порт.
Порты не отображаются на хост-машинах, только на других сервисах.
mysql:
image: mysql:5.7
expose:
- "3306"
Если я сделаю docker-compose ps
, это будет выглядеть так:
Name Command State Ports
---------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp
Ответ 2
порты:
- Активирует контейнер для прослушивания указанных портов из мира за пределами докера (это может быть тот же хост-компьютер или другой компьютер) И также доступный мир внутри докера.
- Можно указать более одного порта (поэтому порты не порты)
выставить:
- Активирует контейнер для прослушивания определенного порта только из мира внутри докера И недоступного мира вне докера.
- Можно указать только один порт
Ответ 3
Порты Этот раздел используется для определения соответствия между хост-сервером и контейнером Docker.
ports:
- 10005:80
Это означает, что приложение, работающее внутри контейнера, открыто на порт 80. Но внешняя система или объект не могут получить к нему доступ, поэтому его необходимо сопоставить с портом хост-сервера.
Примечание. Необходимо открыть порт хоста 10005 и изменить правила брандмауэра, чтобы разрешить внешним объектам доступ к приложению.
Они могут использовать
http://{host IP}: 10005
что-то вроде этого
EXPOSE Это используется исключительно для определения порта, на котором приложение работает внутри контейнера Docker.
Вы также можете определить это в dockerfile. Как правило, это хорошая и широко используемая практика для определения EXPOSE внутри dockerfile, потому что очень редко кто-либо запускает их на другом порту, чем порт 80 по умолчанию
Ответ 4
Я полностью согласен с ответами раньше. Я просто хотел бы упомянуть, что различие между expose и портами является частью концепции безопасности в Docker. Это идет рука об руку с сетью докера. Например:
Представьте себе приложение с веб-интерфейсом и базой данных. Внешний мир нуждается в доступе к веб-интерфейсу (возможно, через порт 80), но только самому серверу необходим доступ к хосту и порту базы данных. При использовании определенного пользователем моста необходимо открыть только веб-порт, а приложению базы данных не нужно открывать какие-либо порты, поскольку веб-интерфейс может достичь его через определенный пользователем мост.
Это частый случай использования при настройке сетевой архитектуры в Docker. Например, в мостовой сети по умолчанию недоступны порты из внешнего мира. Для этого вы можете открыть точку входа с помощью "портов". С помощью "выставить" вы определяете связь внутри сети. Если вы хотите выставить порты по умолчанию, вам не нужно определять "выставлять" в вашем файле docker-compose.
Ответ 5
Порты
Раздел ports
будет публиковать порты на хосте. Docker настроит переадресацию для определенного порта из хост-сети в контейнер. По умолчанию это реализовано с помощью прокси-процесса пользовательского пространства (docker-Proxy
), который прослушивает первый порт и пересылается в контейнер, который должен прослушивать вторую точку. Если контейнер не прослушивает порт назначения, вы все равно увидите что-то прослушивающее на хосте, но получит отказ в соединении, если вы попытаетесь подключиться к этому порту хоста из-за сбоя пересылки в ваш контейнер.
Обратите внимание, что контейнер должен прослушивать все сетевые интерфейсы, поскольку этот прокси-сервер не работает в пространстве имен сети контейнера и не может достичь 127.0.0.1 внутри контейнера. Метод IPv4 для этого заключается в настройке приложения для прослушивания 0.0.0.0
.
Также обратите внимание, что опубликованные порты не работают в обратном направлении. Вы не можете подключиться к службе на хосте из контейнера, опубликовав порт. Вместо этого вы обнаружите ошибки докера, пытающиеся прослушать уже используемый порт хоста.
разоблачать
Expose это документация. Он устанавливает метаданные на изображении, а при запуске - и на контейнере. Обычно вы конфигурируете это в Dockerfile с помощью инструкции EXPOSE
, и она служит документацией для пользователей, запускающих ваш образ, чтобы они знали, по каким портам по умолчанию будет прослушиваться ваше приложение. При настройке с помощью составного файла эти метаданные устанавливаются только для контейнера. Вы можете видеть открытые порты, когда запускаете docker inspect
на образе или контейнере.
Есть несколько инструментов, которые полагаются на открытые порты. В докере флаг -P
будет публиковать все открытые порты на промежуточные порты хоста. Существуют также различные обратные прокси-серверы, которые по умолчанию будут использовать незащищенный порт при отправке трафика в ваше приложение, если вы явно не зададите порт контейнера.
Помимо этих внешних инструментов, expose не оказывает никакого влияния на взаимодействие между контейнерами. Вам нужна только общая сеть докеров и подключение к порту контейнера, чтобы получить доступ к одному контейнеру из другого. Если эта сеть создана пользователем (например, не является мостовой сетью по умолчанию с именем bridge
), вы можете использовать DNS для подключения к другим контейнерам.