#Что означает ошибка и при каких условиях возникает
Если Docker показывает опубликованный порт, но браузер не подключается, проверьте адрес прослушивания внутри контейнера, сопоставление портов и доступ с хоста. EXPOSE в Dockerfile само по себе не открывает порт. Даже при ports сервис обязан слушать правильный внутренний порт и адрес 0.0.0.0 внутри контейнера; привязка к 127.0.0.1 внутри контейнера часто мешает доступу через публикацию.
#Как различить причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Приложение слушает только loopback в контейнереРазработчик запустил сервер на 127.0.0.1 вместо 0.0.0.0. | В самом контейнере запрос к 127.0.0.1 проходит, но опубликованный порт на хосте не открывается. | Изменить bind приложения на 0.0.0.0, сохранив ограничение host IP. |
| Неверная пара HOST:CONTAINERНапример, опубликовано 8080:80, а приложение слушает 8000. | docker compose ps показывает один порт, а журнал приложения — другой. | Сопоставить ports с настоящим портом приложения. |
Порт открыт только локально на хостеПривязка 127.0.0.1:8080:8000 специально не допускает прямой доступ с других машин. | С самого хоста http://127.0.0.1:8080 работает, с другого компьютера — нет. | Проверить, нужен ли внешний доступ; для публикации наружу использовать согласованный обратный прокси. |
| Сеть и брандмауэр препятствуют внешнему подключениюВнешний доступ может блокировать политика сервера, провайдера или сети. | Локальный запрос с хоста проходит, а из другой сети — нет. | Исследовать маршрут и разрешённую схему доступа, не отключая защиту. |
#Пошаговая диагностика и исправление
- Узнайте, что конкретно не открываетсяОткройте браузер на том же компьютере, где работает Docker, и попробуйте http://127.0.0.1:8080 для примера с портом 8080; в своём проекте используйте именно указанный host-порт. Отдельно запишите, получается ли подключиться с другого компьютера. Не считайте эти случаи одинаковыми: если локально работает, причина чаще вне контейнера.
- Откройте Compose и прочтите публикацию портовВ каталоге проекта откройте терминал и выполните
docker compose ps. В колонке PORTS ищите запись127.0.0.1:8080->8000/tcpили подобную. Слева от стрелки — host-порт, справа — порт внутри контейнера. Если указан только8000/tcpбез стрелки, порт может быть лишь открыт для внутренних соединений, но не опубликован хосту. Откройте compose.yaml в редакторе и найдите блокports:у нужного сервиса. - Сверьте порт из журнала программыВыполните
docker compose logs --tail=60 web, где web — имя сервиса. В журнале часто видно, на каком адресе и порту слушает программа:127.0.0.1:8000указывает на контейнерный loopback, а0.0.0.0:8000— на все интерфейсы контейнера. Если журнал ничего не сообщает, проверьте конфигурацию самой программы; не предполагайте порт по одномуEXPOSE. - Проверьте соединение внутри контейнераПри наличии клиентской программы в образе выполните локальный HTTP-запрос к
127.0.0.1:8000из самого контейнера: для образа Python используйтеdocker compose exec web python -c "import urllib.request; print(urllib.request.urlopen('http://127.0.0.1:8000/',timeout=3).status)". Ожидаемый HTTP 200 означает, что сервис внутри доступен. Если Connection refused, сначала устраните ошибку запуска приложения, а не публикацию портов. - Исправьте адрес прослушивания приложенияЕсли в настройках приложения указан 127.0.0.1, в конфигурации самого приложения укажите 0.0.0.0 для контейнерного слушателя. Например, учебный
python -m http.server 8000 --bind 0.0.0.0. Это не означает, что порт следует открывать всему интернету: на стороне хоста вports:безопаснее оставить 127.0.0.1, когда внешний доступ не требуется. Сохраните копию исходной конфигурации для отката. - Исправьте сопоставление портов и проверьте YAMLВ compose.yaml замените неверную пару портов на фактическую, например
127.0.0.1:8080:8000. Прежде чем запускать, выполнитеdocker compose config -q. Если возникла ошибка YAML, проверьте отступы, кавычки, отсутствие конфликтующегоnetwork_mode; не пробуйте бессистемно менять несколько настроек сразу. - Примените только к отдельному тестовому сервисуВ учебном проекте после
docker compose up -dоткройте http://127.0.0.1:8080 в браузере на хосте. При правильной конфигурации появится список файлов сервера Python. Если сервис рабочий, согласуйте пересоздание контейнера с владельцем и проверку зависимостей: кратковременная недоступность возможна. Для отката восстановите сохранённый YAML и повторите согласованное развёртывание. - Если локально работает, но с другой машины нетПроверьте, не задана ли осознанная локальная привязка 127.0.0.1. Вынесение сервиса наружу требует проверки авторизации, TLS, правил брандмауэра и корпоративных ограничений. Не отключайте защиту для проверки. Запишите IP/порт источника, способ обращения и результат браузера, затем обсудите настройку внешнего доступа с администратором.
- Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Минимальный пример для отдельного тестового проекта
services:
web:
image: python:3.12-alpine
command: ["python", "-m", "http.server", "8000", "--bind", "0.0.0.0"]
ports:
- "127.0.0.1:8080:8000"#Как проверить результат и что делать, если проблема осталась
Успех — docker compose ps показывает нужную публикацию, проверка внутри контейнера отвечает, а браузер на хосте открывает http://127.0.0.1:8080. Если внутренний запрос не работает, ищите неисправность приложения. Если внутри работает, а с хоста нет, сверяйте пары портов, привязку host IP и окружение Docker.