n1ro°
RU

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

Как узнать опубликованный порт Docker-контейнера

Как узнать опубликованный порт Docker-контейнера особенно важно, когда host port назначен автоматически или контейнер.

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

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

Как найти host port через docker port, отличить его от container port и проверить binding, протокол и случайно назначенный порт.

Что показывает docker port и чего он не показывает

Команда `docker port` — alias для `docker container port` — выводит опубликованные сопоставления конкретного контейнера. Если вы запускали `docker run -p 8080:80 nginx`, результат для `80/tcp` покажет host binding вроде `0.0.0.0:8080`. Если host port не был задан, например `docker run -p 80 nginx`, Docker выберет доступный ephemeral port, и `docker port` — самый прямой способ узнать его после запуска. При этом команда не сканирует процессы внутри контейнера и не доказывает, что приложение реально слушает целевой порт. Она показывает только настройки публикации Docker. Если Dockerfile содержит `EXPOSE 80`, но контейнер запущен без `-p` или `-P`, внешнего mapping может не быть вообще: EXPOSE — метаданные образа, а не команда публикации. Это различие помогает не тратить время на firewall, когда проблема находится на уровне создания контейнера.

Совет: Сначала выясните mapping через `docker port`, а уже затем проверяйте доступность приложения. Иначе легко диагностировать не тот слой сети.

Посмотреть все или один опубликованный порт

  1. Найдите имя или ID контейнера: `docker ps`. Если контейнер остановлен, добавьте `-a`, чтобы убедиться, что вы смотрите на нужный экземпляр.
  2. Выведите все mappings: `docker port mycontainer`. Формат будет похож на `80/tcp -> 0.0.0.0:54772`.
  3. Если интересует один внутренний порт, выполните `docker port mycontainer 80/tcp`. Для UDP укажите `80/udp`, потому что протокол — часть mapping.
  4. Если команда ничего не выводит, проверьте запуск контейнера: был ли `-p` или `-P`. Наличие `EXPOSE` в image само по себе не публикует порт.
  5. Сверьте host IP. Binding `127.0.0.1:8080` предназначен для доступа с локального хоста, а `0.0.0.0:8080` означает публикацию на всех IPv4-интерфейсах хоста по стандартной конфигурации Docker.
  6. После этого проверьте, что приложение внутри контейнера действительно слушает нужный container port и что запрос идёт на host port, а не на внутренний номер.

Важно: Если сервис должен быть только локальным, публикуйте на `127.0.0.1`, а не оставляйте bind без IP. Docker предупреждает, что публикация без адреса по умолчанию делает порт доступным на всех интерфейсах.

Как читать типичные строки

  • 80/tcp -> 0.0.0.0:8080. TCP 8080 на всех IPv4-интерфейсах хоста перенаправляется в 80/tcp контейнера.
  • 80/tcp -> 127.0.0.1:8080. Порт доступен только через loopback хоста, если нет особой сетевой конфигурации.
  • 53/udp -> 0.0.0.0:5353. Опубликован UDP mapping; проверять его как TCP неправильно.
  • Пусто. У контейнера нет опубликованных mappings либо запрошен другой порт/протокол.

Предупреждение: Не путайте `HOST_PORT:CONTAINER_PORT`: в `-p 8080:80` слева 8080 на хосте, справа 80 внутри контейнера.

Почему docker ps и docker port иногда удобны по-разному

`docker ps` уже показывает колонку PORTS и полезен для быстрого обзора нескольких контейнеров. Но если строка длинная, mappings несколько или нужно программно запросить конкретный внутренний порт, `docker port <name> <port/proto>` проще и однозначнее. В автоматизации не стоит парсить красиво отформатированную таблицу `docker ps` регулярным выражением, если задача сводится к одному mapping. Для более сложного машинного вывода можно использовать `docker inspect` и структуру NetworkSettings.Ports, но это другой уровень детализации. `docker port` хорош как операторская команда: короткий ввод, короткий ответ. Отдельно учитывайте IPv6 — один порт может иметь несколько bindings, и команда способна вернуть несколько строк. Скрипт, который ожидает ровно один адрес, должен обрабатывать этот случай, а не брать первую строку без проверки.

Почему порт опубликован, но сайт всё равно не открывается

Наличие mapping означает, что Docker настроил связь между host port и container port, но приложение может слушать другой порт, завершиться после старта или быть привязано только к `127.0.0.1` внутри контейнера. Для сервера внутри контейнера обычно нужен bind на `0.0.0.0:<container-port>`, чтобы трафик из контейнерной сети доходил до процесса. Проверьте `docker logs`, health status и список процессов, а затем при необходимости зайдите через `docker exec` и посмотрите слушающие сокеты. Также не путайте порт контейнера с портом хоста при curl: с самого хоста обращаются к опубликованному host port, а другой контейнер в одной пользовательской сети обычно обращается к service/container name и внутреннему порту напрямую. Публикация вообще не обязательна для связи контейнер–контейнер внутри одной сети. Если mapping настроен на `127.0.0.1`, удалённый компьютер не должен использовать этот адрес хоста как внешний endpoint.

Диагностика за одну минуту

  • `docker ps` — нужный контейнер запущен и не перезапускается.
  • `docker port <name>` — mapping существует и показывает ожидаемый host port.
  • Протокол совпадает: tcp и udp проверяются отдельно.
  • Приложение внутри слушает именно container port из правой части mapping.
  • Host IP binding соответствует задаче: localhost для локального доступа, внешний интерфейс — только если это действительно нужно.
  • Firewall и внешняя маршрутизация проверяются после того, как сам Docker mapping подтверждён.

Важно: Если база данных или административный интерфейс не должны быть доступны извне, не публикуйте их «на всякий случай». Для связи сервисов используйте Docker network без host publishing.

Как использовать docker port в скриптах без хрупкого парсинга

Если автоматизации нужен один конкретный mapping, запрашивайте его явно с портом и протоколом, например `docker port api 8080/tcp`, а затем обрабатывайте возможные несколько строк. Не предполагайте, что host IP всегда `0.0.0.0` или что binding только один: при IPv4/IPv6 и нескольких публикациях ответ может быть сложнее. Для строгого JSON-контракта лучше перейти на `docker inspect` и читать `NetworkSettings.Ports`, но для shell-проверки оператором `docker port` остаётся проще. Скрипт также должен корректно завершаться, если mapping отсутствует, вместо подстановки пустой строки в curl или конфигурацию другого сервиса. Перед использованием найденного адреса решите, откуда будет идти запрос: endpoint, пригодный для host, не обязательно является правильным адресом для другого контейнера в той же Docker network.

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

`docker ps` уже показывает колонку PORTS и полезен для быстрого обзора нескольких контейнеров. Но если строка длинная, mappings несколько или нужно программно запросить конкретный внутренний порт, `docker port <name> <port/proto>` проще и однозначнее. В автоматизации не стоит парсить красиво отформатированную таблицу `docker ps` регулярным выражением, если задача сводится к одному mapping. Для более сложного машинного вывода можно использовать `docker inspect` и структуру NetworkSettings.Ports…

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

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