n1ro°
RU

Текст и данные · Инструкция

Dockerfile EXPOSE не открывает порт: что делать

EXPOSE в Dockerfile — это метаданные о порте приложения, а не правило публикации на хост. Поэтому добавление EXPOSE 8080 не создаёт localhost:8080.

Редакция N1RO · Проверено

Короткий ответ

EXPOSE в Dockerfile не публикует порт на host: он описывает, какой порт слушает приложение. Для внешнего доступа используйте `docker run -p` или `ports` в Compose.

Что важно знать про Docker EXPOSE

Типичная ошибка — добавить `EXPOSE 8080`, открыть localhost:8080 и ожидать соединение. Но публикация host port происходит на этапе запуска контейнера. Проверяйте три уровня: процесс действительно слушает нужный port внутри container; создан host-to-container mapping; firewall и bind address приложения не блокируют доступ.

Совет: Пишите EXPOSE как документацию порта приложения, а publish задавайте отдельно.

Как опубликовать container port

  1. Проверьте порт процесса внутри контейнера.
  2. Оставьте EXPOSE как документацию.
  3. Запустите с `-p host:container`.
  4. Проверьте mapping через docker ps/docker port.
  5. Если не работает, проверьте bind address и firewall.

Предупреждение: Не публикуйте сервис на всех интерфейсах без необходимости — особенно базы и debug-порты.

Нюансы: container port и host port

`EXPOSE` полезен как metadata и документация image. Он сообщает ожидаемый порт, но сам по себе не создаёт правило публикации на host. Адрес публикации тоже важен. Binding на `127.0.0.1` ограничивает доступ локальной машиной; публикация на всех interfaces может открыть сервис в сеть.

Важно: Проверяйте две цифры отдельно: host port и container port.

Пример: host 8080 → container 80

Nginx слушает 80 внутри image. `EXPOSE 80` это описывает, а `docker run -p 8080:80 nginx` публикует host port 8080.

Как опубликовать порт правильно

Сначала выясните, какой порт слушает приложение внутри container. Затем запустите, например, `docker run -p 127.0.0.1:8080:80 image`, если приложение слушает 80 и доступ нужен только локально. Для внешнего интерфейса меняется host binding — это отдельное решение безопасности, не функция EXPOSE.

Если публикация есть, а соединения нет

Проверьте `docker ps`/inspect для фактического port mapping и убедитесь, что процесс слушает не только `127.0.0.1` внутри контейнера, если ожидаются входящие соединения через container interface. Также проверьте, что перепутаны не host:container части пары. EXPOSE здесь ничего автоматически не исправляет.

EXPOSE и publish

  • Установлен фактический listening port процесса внутри контейнера.
  • Port mapping проверен в порядке host:container и соответствует нужному интерфейсу host.
  • Сервис внутри контейнера слушает адрес, доступный через container network.
  • Лишние database/debug ports не опубликованы наружу без необходимости.

Что учитывать

Типичная ошибка — добавить `EXPOSE 8080`, открыть localhost:8080 и ожидать соединение. Но публикация host port происходит на этапе запуска контейнера. Проверяйте три уровня: процесс действительно слушает нужный port внутри container; создан host-to-container mapping; firewall и bind address приложения не блокируют доступ.

Источники и проверка

Фактическая часть сверена по первичным источникам (в т.ч. Dockerfile reference). Пример и формулировки — редакция N1RO на 2026-09-22.