🐳 Когда объединение сетей Docker неудобно, а нужно срочно связаться через порт хоста

Обычно для связи между контейнерами создают общую мостовую сеть и вызывают по имени службы (например, http://app-b:8080). Но иногда в жизни возникают обстоятельства, когда следовать стандартным правилам невозможно.

Используйте этот метод в следующих "непредвиденных ситуациях"

  • При необходимости связи со службами, установленными непосредственно на хосте: Когда DB или Redis установлены непосредственно на ОС хоста, а не в контейнере, и объединение сетей невозможно.
  • При работе с чужим контейнером, когда страшно менять сетевые настройки: Когда вы опасаетесь, что принудительное включение вашего контейнера в сложную, неуправляемую вами сетевую конфигурацию может привести к сбоям.
  • При необходимости "временной" проверки соединения во время локальной разработки: Когда проектирование сети не имеет значения, и нужно просто немедленно проверить, проходит ли запрос к службе, доступной через порт хоста.

В таких случаях полезным "чит-кодом" является host.docker.internal.

Связь между контейнерами через хост


Решение: "Окно в мир за пределами контейнера" host.docker.internal

Если внутри контейнера вы обратитесь к 127.0.0.1, вы увидите только самого себя (контейнер). Однако, используя специальный домен host.docker.internal, вы можете "пробить" стену контейнера и получить IP-адрес хост-машины.

Пример кода Python (DRF):

# Вместо 'localhost' используйте 'host.docker.internal' для обращения к порту хоста.
# Если App-B привязан к порту 8080 на хосте, вызов будет выглядеть так:
NEXTCLOUD_URL = "http://host.docker.internal:8080"

response = requests.get(NEXTCLOUD_URL)


⚠️ Для пользователей Linux необходима "ручная настройка"

В Docker Desktop (Mac/Windows) это работает по умолчанию, но на чистом Linux-сервере Docker не назначает этот домен автоматически. Необходимо явно указать при сборке или запуске, что "этот домен означает IP-адрес хоста".

Пример настройки Docker Compose:

services:
  drf-app:
    image: my-drf-app-image
    extra_hosts:
      # Объявление доступа к шлюзу хоста под именем host.docker.internal
      - "host.docker.internal:host-gateway"


Это не всегда лучшее решение

Повторюсь, этот метод является скорее крайней мерой.

  1. Наилучший подход: Создать общую мостовую сеть и общаться по именам контейнеров (наиболее безопасно).
  2. Причины для использования этого метода: Необходимость доступа к процессам, запущенным непосредственно на хосте, или когда сетевую структуру невозможно объединить в "изолированной" среде.

Используйте этот "запасной выход", записанный в прошлом году, только как скрытую карту, когда стандартные методы не работают!