Коротка відповідь:
EXPOSE
- це спосіб документування
--publish
(Або -p
) є способом відображення на хост - порт до включеному контейнерного порту
Зауважте нижче:
EXPOSE
пов'язаний з Dockerfiles
( документування )
--publish
пов'язано з docker run ...
( виконання / час виконання )
Розкриття та публікація портів
У мережах Docker є два різних механізми, які безпосередньо включають мережеві порти: відкриття та публікація портів. Це стосується мостової мережі за замовчуванням та визначених користувачем мостових мереж.
Ви відкриваєте порти, використовуючи EXPOSE
ключове слово в Dockerfile або --expose
прапор для запуску докера . Розкриття портів - це спосіб документувати, які порти використовуються, але насправді не відображає та не відкриває жодних портів . Розкривати порти необов’язково.
Ви публікуєте порти, використовуючи --publish
або --publish-all
прапор для docker run
. Це повідомляє Docker, які порти відкривати в мережевому інтерфейсі контейнера. Коли порт публікується, він відображається на доступний порт високого замовлення (вище, ніж 30000
) на хост-машині, якщо ви не вказали порт, для якого потрібно виконати карту на хост-машині під час виконання. Ви не можете вказати порт, на який буде розміщено карту на хост-машині під час створення зображення (у Dockerfile), оскільки немає способу гарантувати, що порт буде доступний на хост-машині, де ви запускаєте зображення .
від: Мережа контейнерів Docker
Оновлення жовтня 2019 року : вищевказаний фрагмент тексту більше не міститься в документах, але тут знаходиться архівована версія: docs.docker.com/v17.09/engine/userguide/networking/#exposed-and-publishing-ports
Можливо, поточна документація наведена нижче:
Опубліковані порти
За замовчуванням, коли ви створюєте контейнер, він не публікує жодного зі своїх портів у зовнішній світ. Щоб зробити порт доступним для служб за межами Docker або контейнерів Docker, які не підключені до мережі контейнера, використовуйте прапор --publish
або -p
. Це створює правило брандмауера, яке відображає порт контейнера на порт хоста Docker.
і їх можна знайти тут: docs.docker.com/config/containers/container-networking/#publish-ports
Також,
ВИДАЧА
... EXPOSE
Інструкція фактично не публікує порт . Він функціонує як тип документації між людиною, яка створює зображення, і особою, яка управляє контейнером, про які порти призначені для публікації.
від: Довідкова довідка
Доступ до послуг, коли 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
.