Відповіді:
Відповідно до довідкової композиції ,
Викрийте порти . Або вкажіть обидва порти (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: // {хост IP}: 10005
щось на зразок цього
ЕКСПОЗИЦІЯ Використовується виключно для визначення порту, на якому працює програма всередині контейнера докера.
Ви також можете визначити його в dockerfile. Як правило, для визначення EXPOSE всередині dockerfile є хорошою та широко застосовуваною практикою, оскільки дуже рідко хтось запускає їх на інший порт, ніж 80 порт за замовчуванням.
У ports
розділі публікуються порти на хості. Docker встановить перехід для конкретного порту з хост-мережі в контейнер. За замовчуванням це реалізується з процесом проксі-сервера користувача ( docker-proxy
), який прослуховує на першому порту, і пересилає в контейнер, який потрібно слухати у другому пункті. Якщо контейнер не прослуховує порт порту, ви все одно побачите щось прослуховування на хості, але отримаєте з'єднання відмовлено, якщо ви спробуєте підключитися до цього хост-порту, від невдалого переходу в ваш контейнер.
Зауважте, контейнер повинен слухати на всіх мережевих інтерфейсах, оскільки цей проксі не працює в мережевому просторі імен контейнера і не може досягти 127.0.0.1 всередині контейнера. Метод IPv4 для цього полягає в налаштуванні програми на прослуховування 0.0.0.0
.
Також зауважте, що опубліковані порти не працюють у зворотному напрямку. Ви не можете підключитися до послуги на хості з контейнера, опублікувавши порт. Натомість ви знайдете помилки докера, намагаючись прослухати вже використовуваний порт хосту.
Експозиція - це документація. Він встановлює метадані на зображення, а під час запуску - і на контейнер. Зазвичай ви налаштовуєте це в Dockerfile з EXPOSE
інструкцією, і він слугує документацією для користувачів, які керують вашим зображенням, щоб вони знали, на яких портах за замовчуванням ваша програма прослуховуватиме. У налаштуваннях із композиційним файлом ці метадані встановлюються лише на контейнері. Ви можете побачити відкриті порти під час запуску а docker inspect
на зображенні чи контейнері.
Є кілька інструментів, які покладаються на відкриті порти. У docker -P
прапор публікує всі відкриті порти на ефемерних портах хоста. Існують також різні зворотні проксі-сервери, які за замовчуванням використовують відкритий порт під час надсилання трафіку у вашу програму, якщо ви явно не встановите порт контейнера.
Окрім цих зовнішніх інструментів, експозиція взагалі не впливає на мережу між контейнерами. Вам потрібна лише загальна мережа докерів та підключення до порту контейнера, щоб отримати доступ до одного контейнера з іншого. Якщо ця мережа створена користувачем (наприклад, не названа мостова мережа за замовчуванням bridge
), ви можете використовувати DNS для підключення до інших контейнерів.
Я повністю згоден з відповідями раніше. Мені просто хочеться зазначити, що різниця між експонацією та портами є частиною концепції безпеки в docker. Це йде рука об руку з мережею докера. Наприклад:
Уявіть програму з веб-інтернетом та базою даних бази даних. Зовнішній світ потребує доступу до веб-інтерфейсу (можливо, до порту 80), але лише сам бек-енд потребує доступу до хоста бази даних та порту. Використовуючи визначений користувачем міст, потрібно відкривати лише веб-порт, а додатку бази даних не потрібно відкривати жодні порти, оскільки веб-фронт може дістатись до нього через визначений користувачем міст.
Це звичайний випадок використання під час налаштування мережевої архітектури в docker. Так, наприклад, у мостовій мережі за замовчуванням не доступні порти із зовнішнього світу. Для цього ви можете відкрити точку вступу за допомогою "портів". Використовуючи "експонувати", ви визначаєте зв'язок всередині мережі. Якщо ви хочете відкрити порти за замовчуванням, вам не потрібно визначати "expose" у вашому файлі docker-compose.
expose
у значенніdocker-compose
? Наскільки я можу сказати, вам не потрібно вказувати експозицію, щоб зробити порти доступними для пов'язаних служб.