EXPOSE в Dockerfile только описывает, какие порты слушает приложение внутри контейнера, и служит документацией/метаданными. Проброс порта через -p или ports: реально открывает порт контейнера на хосте и делает его доступным извне.
EXPOSE — это инструкция в Dockerfile, которая добавляет к образу метаданные о том, на каких портах контейнер ожидает входящие соединения. Она не настраивает сетевые правила и сама по себе не делает сервис доступным с хоста или из внешней сети. Проброс порта (publish) настраивается при запуске контейнера через docker run -p или секцию ports: в Docker Compose и создает реальное правило сопоставления порта контейнера порту хоста. Это правило позволяет подключаться к контейнеру снаружи, в то время как без проброса доступ обычно возможен только из внутренней сети Docker (например, между контейнерами). Важный момент: проброс порта можно сделать и без EXPOSE, а EXPOSE можно указать без публикации порта — тогда это будет лишь документация для людей и инструментов (например, подсказка для --publish-all).
EXPOSE — «контейнер слушает на этих портах», это декларация и документация внутри образа.EXPOSE помогает понять и задокументировать интерфейс сервиса, а проброс порта решает, будет ли этот интерфейс виден вне Docker-хоста и под какими портами.В этом примере в Dockerfile мы документируем, что веб-сервер внутри контейнера слушает порт 80, но пока ничего не публикуем на хосте.
Теперь запустим контейнер с пробросом порта: параметр -p 8080:80 (или секция ports: в Compose) сопоставляет порт 80 внутри контейнера с портом 8080 на хосте, и именно это делает сервис доступным снаружи.
Отметьте свой прогресс