ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

Порты Docker: publish, EXPOSE и доступ через localhost

Автор: · Обновлено

У веб-сервера внутри контейнера и у порта компьютера разные адресные пространства. В этом уроке запустим Nginx на локальном порту 18080, проверим отображение и разберём, почему…

У веб-сервера внутри контейнера и у порта компьютера разные адресные пространства. В этом уроке запустим Nginx на локальном порту 18080, проверим отображение и разберём, почему EXPOSE 80 само по себе не открывает страницу в браузере. Наличие слова localhost в сообщении ещё не определяет, на какой машине выполняется запрос.

Читать пару портов слева направо

В -p 127.0.0.1:18080:80 адрес и первый порт принадлежат хосту Docker, последний — контейнеру. Браузер на этом хосте обращается к http://127.0.0.1:18080, а Nginx внутри слушает порт 80. Если оставить только -p 18080:80, по умолчанию публикация может охватывать все адреса хоста. Для локального учебного сервиса выбираем loopback явно. Публикация портов.

docker run -d --name yk-port-demo -p 127.0.0.1:18080:80 nginx:1.28-alpine
docker port yk-port-demo
curl -I http://127.0.0.1:18080

Ожидайте отображение контейнерного 80/tcp на 127.0.0.1:18080 и HTTP-ответ Nginx. Если порт занят, выберите свободный host port, например 18081, и поменяйте адрес curl. Пересборка образа не освобождает занятый порт хоста.

EXPOSE описывает, publish подключает

Инструкция Dockerfile EXPOSE сообщает, какой порт предполагается использовать. Она не заставляет процесс слушать его, не изменяет настройки Nginx и не публикует порт на хосте. docker run -P использует объявленные порты для автоматического выбора host ports; фактические значения смотрите через docker port, а не угадывайте. Семантика EXPOSE.

В Compose ports выполняет публикацию. Для нашего контейнера эквивалентная запись:

services:
  web:
    image: nginx:1.28-alpine
    ports:
      - "127.0.0.1:18080:80"

Запускайте этот вариант после удаления yk-port-demo, иначе два сервиса будут конкурировать за 18080. Поле expose не заменяет ports для браузера на хосте. Для обмена между контейнерами одной сети публикация на хост вообще обычно не нужна.

Четыре последовательные проверки

Сначала выясните, жив ли контейнер: docker ps -a и docker logs yk-port-demo. Затем проверьте приложение внутри: оно должно слушать интерфейс, доступный через контейнерную сеть, обычно 0.0.0.0, а не только собственный 127.0.0.1. Третьим шагом сравните публикацию через docker port. Последним проверьте адрес клиента, firewall и маршрут до Docker host.

Если Docker context удалённый, localhost ноутбука не равен localhost сервера. При Windows/WSL учитывайте, где открыт браузер и где daemon: Docker Desktop организует интеграцию, но дополнительная VM, VPN или удалённый context меняют путь. Запишите эти узлы до изменения правил доступа.

Записи Windows DistributedCOM с CLSID/APPID относятся к другой подсистеме. Формулировка «контейнер приложения» в Event Viewer не доказывает проблему Docker ports; её разбор находится в [уроке о DCOM](/lessons/without-university/docker-containerization/docker-developer-34).

Практика

Остановите первый контейнер и создайте два Nginx с разными host ports, но одинаковым портом 80 внутри. Объясните, почему внутренние порты не конфликтуют. Сравните docker port для обоих и выполните curl к каждому. В завершение удалите только свои контейнеры; чужие службы с занятыми портами не трогайте. Проверяемый результат — умение указать адрес клиента, host port и container port без смешения этих трёх величин.

Источники