[Docker] Связь между контейнерами через хост-порт без общего сетевого соединения (host.docker.internal)
Теги: Docker, DevOps, Сеть, host.docker.internal
1. Проблема
В разработческой среде часто управляют несколькими сервисами с помощью Docker.
-
App-A(например, DRF) находится вnetwork-A. -
App-B(например, Nextcloud) находится вnetwork-B. -
Оба контейнера запускаются на одной и той же хост-машине.
-
App-Bпривязан к8080порту на хосте. (например,docker run -p 8080:80 ...)
App-A должен вызвать App-B через API. Я не хочу связывать две сети через мост. Разве нельзя просто вызвать хост-порт 8080?
Если вызвать localhost:8080 или 127.0.0.1:8080 из контейнера, то это будет ссылаться не на хост-машину, а на сам контейнер.
2. Решение: host.docker.internal
Самое простое решение — использовать специальное DNS-имя host.docker.internal.
host.docker.internal: специальное имя хоста, которое интерпретируется как IP-адрес хост-машины внутри контейнера.
В коде App-A (DRF), когда вызывается Nextcloud, задайте URL следующим образом.
# Внутренний код DRF (App-A)
import requests
# Используйте 'host.docker.internal' вместо 'localhost'.
NEXTCLOUD_URL = "http://host.docker.internal:8080"
try:
response = requests.get(NEXTCLOUD_URL)
print(f"Успешное подключение к Nextcloud: {response.status_code}")
except requests.exceptions.ConnectionError:
print("Ошибка подключения к Nextcloud")
То же самое применимо и для тестирования с помощью curl внутри контейнера.
# Выполнение внутри контейнера App-A
curl http://host.docker.internal:8080
3. ⚠️ Важно: Настройка окружения Linux
Пользователи Docker Desktop (macOS, Windows) могут использовать host.docker.internal по умолчанию.
Однако для Linux-хостов нужно добавить эту настройку вручную. Вы можете использовать специальное ключевое слово host-gateway для сопоставления IP хоста.
Способ 1: Использование docker run
Добавьте флаг --add-host.
docker run \
--add-host=host.docker.internal:host-gateway \
--network network-A \
my-drf-app-image
Способ 2: Использование docker-compose.yml
Добавьте extra_hosts к сервису App-A (DRF).
services:
drf-app:
image: my-drf-app-image
networks:
- network-A
extra_hosts:
# Сопоставление host.docker.internal с IP хоста (host-gateway)
- "host.docker.internal:host-gateway"
# ... (определение network-A) ...
4. Итоги
При взаимодействии между изолированными сетями Docker нет необходимости усложнять связь сетей.
-
Привяжите целевой контейнер (Nextcloud) к хост-порту (
8080). -
Сделайте запрос из контейнера (DRF) по адресу
http://host.docker.internal:8080. -
Если хост на Linux, не забудьте добавить настройку
extra_hosts(host.docker.internal:host-gateway) в вызывающий контейнер.
Комментариев нет.