[Docker] 네트워크 공유 없이, 호스트 포트로 컨테이너간 통신하기 (host.docker.internal)
태그: Docker, DevOps, Network, host.docker.internal
1. 문제 상황
개발 환경에서 여러 서비스를 도커로 관리할 때가 많습니다.
-
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
가장 간단한 해결책은 host.docker.internal이라는 특수 DNS 이름을 사용하는 것입니다.
host.docker.internal: 컨테이너 내부에서 호스트 머신의 IP 주소로 해석되는 특별한 호스트 이름입니다.
App-A (DRF)의 코드에서 Nextcloud를 호출할 때, URL을 다음과 같이 설정합니다.
# DRF (App-A) 내부 코드
import requests
# 'localhost' 대신 'host.docker.internal'을 사용합니다.
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 사용 시
App-A (DRF) 서비스에 extra_hosts를 추가합니다.
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. 요약
분리된 도커 네트워크 간 통신 시, 네트워크를 복잡하게 연결할 필요 없습니다.
-
호출 대상 컨테이너(Nextcloud)를 호스트 포트(
8080)에 바인딩합니다. -
호출하는 컨테이너(DRF)에서
http://host.docker.internal:8080주소로 요청합니다. -
호스트가 Linux라면, 호출하는 컨테이너에
extra_hosts(host.docker.internal:host-gateway) 설정을 잊지 않고 추가합니다.
댓글이 없습니다.