Я подозреваю, что проблема может заключаться в том, что вы путаете инструкцию EXPOSE
времени сборки с флагом publish
времени выполнения. Без последнего любые контейнеры на вашей виртуальной машине были бы недоступны для хост-машины.
Некоторые сведения:
Инструкция EXPOSE
лучше всего воспринимается как документация; это не влияет на работу контейнеров . Из документов :
Команда EXPOSE фактически не публикует sh порт. Он функционирует как тип документации между человеком, который создает образ, и человеком, который запускает контейнер, о том, какие порты предназначены для публикации.
На первый взгляд кажется странным, но это по уважительной причине: сам образ не имеет разрешений для объявления сопоставлений портов хоста - это зависит от времени выполнения контейнера и от того, кто его использует (вы!).
Способ сделать это - передать флаг --publish
или -p
команде docker run
, что позволит вам определить соответствие между портом, открытым в сети контейнера, и портом на хосте. машина. Так, например, если бы я хотел запустить контейнер nginx
, к которому можно получить доступ через порт 8080 на моем локальном хосте, я бы запустил: docker run --rm -d -p 8080:80 nginx
. Затем работающий контейнер доступен на localhost:8080
на хосте. Конечно, вы также можете использовать это для демонстрации контейнерных портов с одного хоста на другой. Без этого любая сетевая конфигурация в вашем Dockerfile выполняется в контексте сети контейнеров и в основном недоступна для хоста.
TL; DR: вам, вероятно, просто нужно опубликовать sh ваши порты, когда вы создаете и запускаете контейнер на вашей виртуальной машине: docker run -p {vm_host_port}:{container_port} {image_name}
. Обратите внимание, что сопоставления портов нельзя добавлять или изменять для существующих контейнеров; вам придется уничтожить контейнер и воссоздать его.
Примечание: хотя docker run
быстро и просто, оно может быстро стать неуправляемым по мере роста вашего проекта и добавления переменных среды, присоедините объемы, определить зависимости между контейнерами и т. д. c. Альтернативой со встроенной поддержкой является docker-compose
, которая позволяет вам декларативно определять среду выполнения вашего контейнера (или контейнеров) в YAML - в основном, в том месте, где заканчивается Dockerfile. И после того, как он настроен, вы можете просто запустить docker-compose up
, вместо того, чтобы вводить длинные команды docker
, и тратить время на отладку, когда вы забыли включить флаг, et c. Точно так же, как мы используем Dockerfile
s, чтобы иметь декларативное, управляемое версиями описание того, как построить наш образ, мне нравится думать о docker-compose
как об одном способе создания декларативного, управляемого версиями описания о том, как запустить и организовать наш образ (ы).
Надеюсь, это поможет!